Hxcy = {
	emptyFn : function() {
		Ext.MessageBox.show({
			title : '提示信息',
			width : 200,
			msg : "<br />此功能暂时未能实现",
			buttons : Ext.MessageBox.OK,
			icon : Ext.MessageBox.INFO
		});
	},
	start : 'page.start',
	limit : 'page.limit',
	START : 0,
	LIMIT : 20,
	CPT : '/zuoyue'
};
Ext.BLANK_IMAGE_URL = Hxcy.CPT + '/js/ext-3.0.3/resources/images/default/s.gif';

Ext.chart.Chart.CHART_URL=Hxcy.CPT +'/js/ext-3.0.3/resources/charts.swf';

Ext.QuickTips.init();

Hxcy.Util = function() {
	return {
		applyIf : function(dest, source) {
			for (var p in source) {
				if (typeof dest[p] == "undefined") {// 测试在表单配置是否有此成员
					dest[p] = source[p];// 没有则添加
				} else if (typeof dest[p] == "object" && dest.hasOwnProperty(p)) {// 有则测试其是不是一个对象
					this.applyIf(dest[p], source[p]);
				}
			}
		},
		list : function(o, all) {
			var v = "";
			for (var p in o) {
				if(o.hasOwnProperty(p)){
					v += "属性:" + p + "值:" + o[p]+"\n";
				}
			}
			return v;
		},
		cfg : function(subConfig, baseConfig) {
			if (!subConfig || !baseConfig) {
				alert("在配置属性进行复制的时候,目标与源都不能为空");
			}
			if (!subConfig.init) {
				Hxcy.Util.applyIf(subConfig, baseConfig);
				subConfig.init = true;
			}
			return subConfig;
		},
		msg : function(msg, cfg) {
			cfg = cfg || {};
			cfg = Ext.isFunction(cfg) ? {cb : cfg} : cfg;
			var base = {
				title : '消息',
				msg : "<br />" + msg,
				buttons : Ext.Msg.OK,
				icon : Ext.Msg.INFO,
				fn : cfg.cb || Ext.emptyFn
			};
			Ext.applyIf(cfg, base);
			Ext.MessageBox.show(cfg);
		},
		warn : function(msg, cfg) {
			cfg = cfg || {};
			cfg = Ext.isFunction(cfg) ? {cb : cfg} : cfg;
			var base = {
				title : '警告',
				msg : "<br />" + msg,
				buttons : Ext.Msg.OK,
				icon : Ext.Msg.WARNING,
				fn : cfg.cb || Ext.emptyFn
			};
			Ext.applyIf(cfg, base);
			Ext.MessageBox.show(cfg);
		},
		error : function(msg, cfg) {
			cfg = cfg || {};
			cfg = Ext.isFunction(cfg) ? {cb : cfg} : cfg;
			var base = {
				title : '错误',
				msg : "<br />" + msg,
				buttons : Ext.Msg.OK,
				icon : Ext.Msg.ERROR,
				fn : cfg.cb || Ext.emptyFn
			};
			Ext.applyIf(cfg, base);
			Ext.MessageBox.show(cfg);
		},
		confirm : function(msg, cfg) {
			cfg = cfg || {};
			cfg = Ext.isFunction(cfg) ? {cb : cfg} : cfg;
			var base = {
                title : "确认",
                msg : msg,
                width : 200,
                buttons: Ext.Msg.YESNO,
                fn: cfg.cb || Ext.emptyFn,
                icon: Ext.Msg.QUESTION
			};
			Ext.applyIf(cfg, base);
			Ext.MessageBox.show(cfg);
		},
		prompt : function(msg, cfg){
			cfg = cfg || {};
			cfg = Ext.isFunction(cfg) ? {cb : cfg} : cfg;
			var base = {
                title : '输入框',
                msg : msg,
                buttons: Ext.Msg.OKCANCEL,
                minWidth:250,
                fn : cfg.cb || Ext.emptyFn,
                prompt:true
            };
            Ext.applyIf(cfg, base);
			Ext.MessageBox.show(cfg);
		}
	}
}();

Hxcy.overrideIf = 'function' === typeof Hxcy.overrideIf ? Hxcy.overrideIf : function(origclass, overrides) {
	if(overrides) {
		var p = origclass.prototype;
		for(var method in overrides) {
			if(!p[method]) {
				p[method] = overrides[method];
			}
		}
	}
};

if('function' !== typeof RegExp.escape) {
	/**
	 * Escapes regular expression
	 * @param {String} s
	 * @return {String} The escaped string
	 * @static
	 */
	RegExp.escape = function(s) {
		if('string' !== typeof s) {
			return s;
		}
		return s.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1');
	};
}
Hxcy.overrideIf(RegExp, {

	/**
	 * Clones RegExp object
	 * @return {RegExp} Clone of this RegExp
	 */
	 clone:function() {
		return new RegExp(this);
	} // eo function clone
});

Hxcy.TPL = {
	form : {
		xtype : 'form',
		//defaultType : 'textfield',
		layoutConfig : {// 专有布局配置
			labelWidth : 75,
			labelPad : 20,// 标签内边距
			labelAlign : "left",
			labelSeparator : '：'
		},
		defaults : {// 应用于所有子组件的公共配置
			width : 240,
			validateOnBlur : false,// 这里阻止客户端检验的表象效果发生,而最终是否校验决定于最后提交时的选项
			validationEvent : false,
			msgTarget : 'side'
		},
		border : false,
		bodyStyle : 'padding:10px;',
		listeners : {
			beforeaction : function(form, action) {
				form.clearInvalid();
			}
		}
	}
};

Hxcy.request = function(cfg){
	cfg = cfg || {};
	Ext.isString(cfg) ? cfg = {url : cfg} : '';
	var defaultCfg = {
		url:cfg.url,
		success:function(rs,o){
			var rst = Ext.decode(rs.responseText);
			if(cfg.success){
				cfg.success(rst, rst.messages)
			} else if(cfg.debug){
				Hxcy.Util.msg(Hxcy.Util.list(rst));
			} else {
				Hxcy.Util.msg(rst.messages);
			}
		},
		success:function(rs,o){
			var rst = Ext.decode(rs.responseText);
			if(rst.success||o.async===false){//要特别注意：请求权限是一非标准的信息格式
				if(cfg.success){
					cfg.success(rst, o);
				} else {
					Hxcy.Util.msg(rst.messages);
				}
			} else if(cfg.debug){
				Hxcy.Util.msg(Hxcy.Util.list(rst));
			} else {
				if(cfg.failure){
					cfg.failure(rst, 0)
				} else {
					Risen.Util.error(rst.actionErrors[0]||'操作失败');
				}
			}
		},
		failure : function(rs, o) {
			var rst = Ext.decode(rs.responseText);
			Hxcy.Util.error(rst.actionErrors);
			if(cfg.failure){
				cfg.failure(rst, rst.actionErrors)
			} else if(cfg.debug){
				Hxcy.Util.error(Hxcy.Util.list(rst));
			} else {
				Hxcy.Util.error(rst.actionErrors);
			}
		},
		params: cfg.params,
		form : cfg.form
	};
	Ext.Ajax.request(Ext.applyIf(defaultCfg, cfg));
};

Ext.Ajax.on('requestcomplete',function checkUserSessionStatus(conn,response,options){
	if (!response.getAllResponseHeaders||!response.getAllResponseHeaders()) {
		return;
	}
	//Ext重新封装了response对象
	if(typeof response.getResponseHeader('sessionstatus') != 'undefined'){   
		//发现请求超时，退出处理代码...
		Hxcy.Util.error("由于长时间没有与服务器联系或者服务器已经重启,登录已经失效,请重新登录", function(){
			top.location=Hxcy.CPT+"/public/login.jsp";		
		});
	}
	if(typeof response.getResponseHeader('securitystatus') != 'undefined'){   
		Hxcy.Util.error("你访问的资源或执行的操作是受保护的,<br />而你没有相应的授权,如需要执行请与管理员联系");
	}
});


Hxcy.stateMag = function(){
	var provider = new Ext.state.Provider();
	return {
		setProvider : function(stateProvider){
			provider = stateProvider;
		},

		get : function(key, defaultValue){
			return provider.get(key, defaultValue);
		},

		set : function(key, value){
			provider.set(key, value);
		},

		clear : function(key){
			provider.clear(key);
		},

		getProvider : function(){
			return provider;
		}
	};
}();

Hxcy.Factory = function(config){
	config = config || {};
	if (typeof config == "string") {
		config = {ns : config};
	}
	Ext.apply(this, config);
	if (this.ns) {
		this.setNS(this.ns);
	}
	this.idCounter = 1000;
	this.ComponetContainer = {};
	this.dictReader = [{
		name : 'dictId',
		mapping : 'dictId',
		type : 'int'
	}, {
		name : 'itemTitle',
		mapping : 'itemTitle'
	}]
}

Hxcy.Factory['EmptyStore'] = new Ext.data.SimpleStore({fields:[],data:[[]],url:true});

Hxcy.Factory.prototype = {
	createUrl : function(url){
		return url.indexOf('/')==0? url:this.nspath+url;
	},
	setNS : function(ns){
		this.ns = ns;
		this.NS = eval('(' + this.ns + ')');
		this.nspath = Hxcy.CPT+"/"+this.ns.replace(/\./g, "/").toLowerCase()+"/";
		this.prefix = this.ns.replace(/\./g, "-").toLowerCase()+"-";
	},
	setCombo : function(comboId, rd, key){
		var combo = Ext.getCmp(comboId);
		if(combo){
			key = key || rd.get(combo.valueField);
			rd = rd || Hxcy.Factory['EmptyStore'].getAt(0);
			Hxcy.Factory['EmptyStore'].removeAll();
			Hxcy.Factory['EmptyStore'].add(rd);
			combo.setValue(key);
		} else {
			alert('指定的comboId不是一个组件combo组件ID');
		}
	},
	setDataView : function(record, remote){
		if (remote) {
			Hxcy.Factory['EmptyStore'].reader = remote.reader||remote.store.reader;
			var url = remote.url || remote.store.proxy.conn.url;
			url = this.createUrl(url);
			Hxcy.Factory['EmptyStore'].proxy.conn.url = url;
			Hxcy.Factory['EmptyStore'].recordType = remote.recordType||remote.store.recordType;
			Hxcy.Factory['EmptyStore'].load({
				params : remote.params||{},
				callback : remote.callback
			});
		} else {
			Hxcy.Factory['EmptyStore'].removeAll();
			Hxcy.Factory['EmptyStore'].add(record);
		}
	},
	reset : function(record, remote){
		Hxcy.Factory['EmptyStore'].removeAll();
		if (record) {
			Hxcy.Factory['EmptyStore'].add(record);
		} else if (remote) {
			Hxcy.Factory['EmptyStore'].reader = remote.reader||remote.store.reader;
			var url = remote.url || remote.store.proxy.conn.url;
			url = this.createUrl(url);
			Hxcy.Factory['EmptyStore'].proxy.conn.url = url;
			Hxcy.Factory['EmptyStore'].recordType = remote.recordType||remote.store.recordType;
			Hxcy.Factory['EmptyStore'].load({
				params : remote.params||{},
				callback : remote.callback
			});
		} 
	},
	processPermission : function(items, pmnMap){
		for (var i = 0; i < items.length; i++) {
			if (Ext.isObject(items[i])) {
				if(pmnMap[items[i]['key']]||items[i]['key']){//表示具有权限或强制显示
					//注意:这里考虑的情况比较简单,只考虑了menu,tbar,items办存在一种的情况
					var subItms = items[i].menu ? items[i].menu : (items[i].tbar ? items[i].tbar : items[i]['items']);
					if(subItms){
						//处理子组件
						var count = this.processPermission(subItms, pmnMap);
						if (count==0||subItms[0]=='-') {//如果子组件为0则同样删除它的你组件,或只有一个分隔线也删除
							items.splice(i--, 1);
						} else if(items[i].menu){//如果是菜单,则进行初始化
							items[i].menu = new Ext.menu.Menu({items:subItms});
						}
					}
				} else {//表示没有权限,将此组件清理
					items.splice(i--, 1);
				}
			} else {
				;//表示分隔线'-'先等特殊组件
			}
		}
		//处理分隔线
		var current = false;
		for (i = 0; i < items.length; i++) {
			var last = current;
			current = items[i]=='-' ? true : false;
			if(last && current){//如果上一次与这一次都是分隔线则删除这一次的隔线
				items.splice(i--, 1);
			}
			if (i==items.length-1&&current) {
				items.splice(i--, 1);
			}
		}
		//返回处理后的组件数
		return items.length;
	},
	
	processDynamicExprot : function(ctxGrid, args){
		args = args || {};
		var baseArgs = {
			'export' : true,
			oneTimeExport : false,
			dynamicCol : true,
			maxCountOneTime : 8000,
			exportTPL : 'new-tpl.xls'
		};
		//复制基本参数
		Ext.applyIf(args, baseArgs);
		
		var fieldMapper = [];
		var headerMapper = [];
		var colIdx = 0;
		ctxGrid.getCM().getColumnsBy(function(cols, idx){
			var col = this.getColumnAt(idx);
			var name = col.dataIndex.toUpperCase();
			name = !Ext.isEmpty(name) ? "$"+name+"$" : name;
			var unmapping = col.unmapping||name;
			var header = col.header;
			var display = !Ext.isEmpty(unmapping)&&!this.isHidden(idx);
			display ? fieldMapper.push("0"+(colIdx)+":"+unmapping):"";
			display ? headerMapper.push("1"+(colIdx++)+":"+header):"";
		});
		var lop = ctxGrid.getStore().lastOptions;
		lop = lop ? lop.params : {};
		var params = [
			Ext.urlEncode(args)+"&",
			"region=",
			"header:{ER_rps:0-0-"+colIdx+"-2,ER_srps:0-0-"+colIdx+"-1,ER_ptf:{"+encodeURIComponent(headerMapper)+"}},",
			"content:{ER_rps:0-2-"+colIdx+"-1,ER_ptf:{"+encodeURIComponent(fieldMapper)+"}},",
			"footer:{ER_rps:0-0-0-0}&",
			Ext.urlEncode(lop)+"&"+Ext.urlEncode(ctxGrid.getStore().baseParams)
		].join('');
		return params;
	},
	
	setCaretTo : function (obj, pos) { 
		if(obj.createTextRange) {
			var range = obj.createTextRange(); 
			range.move("character", pos); 
			range.select(); 
		} else if(obj.selectionStart) {
			obj.focus(); 
			obj.setSelectionRange(pos, pos); 
		} 
	},
	put : function(name, comp){
		this.ComponetContainer[name] = comp;
	},
	get : function(name){
		return this.ComponetContainer[name];
	},
	remove : function(name){
		delete this.ComponetContainer[name];
	},
	putNS : function(space){
		space = typeof space=='string' ? [space] : space;
		var ns = this.NS;
		for (var index = 0; index < space.length; index++) {
			var spaceCases = space[index].split('.');
			var o = ns;
			for (var caseIndex = 0; caseIndex < spaceCases.length; caseIndex++) {
				o = o[spaceCases[caseIndex]];
			}
			for(var p in o){
				this.ComponetContainer[p]=o[p];
			}
		}
	},
	createRecord : function(fields, values){//简单创建一个临时的记录
		var Record = Ext.data.Record.create(fields);
		var temp = {};
		for(var i=0; i<fields.length; i++){
			temp[fields[i]]=values[i];
		}
		return new Record(temp);
	},
	createCombo : function(cfg){
		cfg = typeof cfg=='string' ? {hiddenName:cfg} : cfg;
		cfg.space = cfg.space || 'formfields-';
		cfg.fieldLabel = cfg.fieldLabel || '';
		var id = this.createComboId(cfg);
		var base = {
			id : id,
			fieldLabel : cfg.hiddenName,
			xtype: 'combo',
			readOnly : true,
			editable : false,
			allowBlank : false,
			triggerAction : 'all',
			valueField : cfg.hiddenName,
			displayField : cfg.hiddenName+'Title',
			store: Hxcy.Factory['EmptyStore'],
			emptyText : '请选择'+cfg.fieldLabel+'...'
		};
		Ext.applyIf(cfg, base);
		return cfg;
	},
	createComboId : function(cfg){
		cfg = typeof cfg=='string' ? {hiddenName:cfg} : cfg;
		cfg.space = cfg.space || 'formfields-';
		return this.prefix+cfg.space+cfg.hiddenName.toLowerCase()+'-combo-'+this.idCounter++;
	},
	createDictCombo : function(cfg){
		cfg.valueField = 'dictId';
		cfg.displayField = 'itemTitle';
		cfg.store = this.createDictStore(cfg.groupName||cfg.fieldLabel);
		return this.createCombo(cfg);
	},
	createPagingToolbar : function(cfg){
		cfg = cfg.store ? cfg : {store : cfg};
		Ext.applyIf(cfg, {
			pageSize : Hxcy.LIMIT,
			paramNames : {
				start : 'page.start',
				limit : 'page.limit'
			},
			displayInfo : true,
			displayMsg : '第{0}条 - 第{1}条 共{2}条',
			emptyMsg : "没有可显示的记录"
		});
		return new Ext.PagingToolbar(cfg);
	},
	createSM : function(single){
		if(single===undefined){
			single = true;
		}
		return new Ext.grid.CheckboxSelectionModel({singleSelect:single});
	},
	createCM : function(cfg){
		if (typeof cfg=='string') {
			cfg = {beanName : cfg};
		}

		var ns = cfg.ns ? eval('(' + cfg.ns + ')') : this.NS;
		var noappend = cfg.noappend;
		var sm = cfg.sm || cfg.beanName+'SM'
		var mapping = cfg.mapping || cfg.beanName+'Mapping'
		
		if (typeof sm=='string') {//如果指定一个sm对象就不需要到容器中去取了
			sm = ns.SM[sm]||this.get(sm);//因为一些空间变量可能会被重新定义,此时以前在此空间下的定义就不存在,但它应该会在工厂容器中
		}
		if (typeof mapping=='string'){
			mapping = ns.Mapping[mapping]||this.get(mapping);
		}
		
		if (noappend!==false) {
			mapping = [sm].concat(mapping);
		}
		cfg.columns = mapping;
		cfg.defaults = cfg.defaults||{};
		cfg.defaults.sortable=cfg.defaults.sortable!==false;
		return new Ext.grid.ColumnModel(cfg);
	},
	createCmbReader : function(cfg) {
		if (Ext.isString(cfg)) {
			cfg = [cfg];
		}
		var cmbRd = [];
		for (var i = 0; i < cfg.length; i++) {
			var beanNameRd = cfg[i];
			if (!beanNameRd.match('Reader$')) {
				beanNameRd = beanNameRd+'Reader';
			}
			if (this.get(beanNameRd)) {
				cmbRd = cmbRd.concat(this.get(beanNameRd));
			} else {
				alert('指定的Reader名称无效');
			}
		}
		return cmbRd;
	},
	createCmbMapping : function(cfg){
		//{beanName:['f1','f2','f3']}基本格式或{beanName:true}或beanName
		var cmbMp = [];
		
		if (Ext.isString(cfg)) {
			var initCfg = cfg;
			cfg = {};
			cfg[initCfg] = true;
		}
		for(var beanName in cfg){
			var fields = cfg[beanName];
			if (fields===true || Ext.isArray(fields)) {
				if (!beanName.match('Mapping$')) {
					beanName = beanName+'Mapping';
				}
				var cm = this.get(beanName);
				if (Ext.isArray(cm)) {
					var key = null;
					Ext.each(cm, function(item){
						key = item['key'] || item['dataIndex'] || item['header'];
						if (fields===true || fields.indexOf(key)>=0) {
							cmbMp.push(item);
							return false;
						}
					});
				} else {
					alert('组合Mapping指定有错误:'+beanName);
					return ;
				}
			} else {
				alert('组合Mapping指定有错误:'+beanName);
				return ;
			}
		}
		return cmbMp;
	},
	createCmbMap : function(cfg){
		//{mapper:{a:beanA, b:beanB}, fields:['a:f1', 'b:f2']}
		if (!Ext.isObject(cfg)) {
			alert('参数必须是一个配置对象');
		}
		if (!Ext.isObject(cfg['mapper'])) {
			alert('参数必须有一个mapper映射对象');
		}
		if (!Ext.isArray(cfg['fields'])) {
			alert('参数必须有一个fields数组对象');
		}
		var mapper = cfg['mapper'];
		for(var m in mapper){
			if (!mapper[m].match('Mapping$')) {
				mapper[m] = mapper[m]+'Mapping';
			}
		}
		var cmbMp = [];
		var me = this;
		Ext.each(cfg['fields'], function(item){
			var two = item.split(':');
			if (two.length==1) {
				two[1] = two[0];
				two[0] = 'df';//设置一个默认缩写
			}
			if (two.length!=2) {
				alert('字段配置必须以唯一冒号分隔');
			}
			var cm = me.get(mapper[two[0]]);//获取待选的CM
			Ext.each(cm, function(f){
				var key = f['key'] || f['dataIndex'] || f['header'];
				if (key==two[1]) {
					cmbMp.push(f);
					return false;
				}
			});
		});
		return cmbMp;
	},
	createAction : function(cfg){
		if (!Ext.isObject(cfg)) {
			cfg = {
				panel : arguments[0],
				text : arguments[1],
				iconCls : arguments[2],
				handler : arguments[3],
				actCtr : arguments[4]
			};
		}
		cfg['text'] =  cfg['text']||'未配置';
		cfg['iconCls'] = cfg['iconCls']||'rscls-ry-16';
		var me = this;
		var hd = cfg['handler'];
		if (hd) {
			cfg['handler'] = Ext.isFunction(hd) ? hd : function(btn, e){ me.get(cfg['panel'])[hd](btn, e); };
		} else {
			cfg['handler'] = Ext.emptyFn;
		}
		var bp = cfg['actCtr'];
		if (bp) {
			cfg['actCtr'] = Ext.isFunction(bp) ? bp : function(btn, e){ me.get(cfg['panel'])[bp](btn, e); };
		} else {
			cfg['actCtr'] = Ext.emptyFn;
		}
		return new Ext.Action({
			text : cfg['text'],
			iconCls : cfg['iconCls'],
			handler : cfg['handler'],
			actCtr : cfg['actCtr']
		});
	},
	createStore : function(cfg){
		cfg.url = this.createUrl(cfg.url);
		var ns = cfg.ns ? eval('(' + cfg.ns + ')') : this.NS;
		var reader = cfg.reader||cfg.beanName+'Reader';
		if (typeof reader=='string') {
			reader = ns && ns.Reader && ns.Reader[reader] ? ns.Reader[reader]: this.get(reader);//因为一些空间变量可能会被重新定义,此时以前在此空间下的定义就不存在,但它应该会在工厂容器中
		}
		cfg.fields = reader;
		var baseCfg = {
			CPT : 'records',
			totalProperty : 'totalCount',
			paramNames : {
				start : 'page.start',
				limit : 'page.limit'
			},
			remoteSort:true
		};
		Ext.applyIf(cfg, baseCfg);
		return new Ext.data.JsonStore(cfg);
	},
	createDictStore : function(groupName){
		var reader = this.dictReader;
		return new Ext.data.JsonStore({
			url : Hxcy.CPT+'/public/listItemsByGroupName.action',
			CPT : 'records',
			totalProperty : 'totalCount',
			autoLoad : true,
			baseParams : {groupName:groupName},
			fields : reader
		});
	},
	createDataView : function(cfg){
		cfg = typeof cfg=='string' ? {beanName:cfg} : cfg;
		var store = cfg.store ||Hxcy.Factory['EmptyStore'];
		delete cfg.store;
		var ns = cfg.ns ? eval('(' + cfg.ns + ')') : this.NS;
		var viewName = cfg.viewName || cfg.beanName+'TPL';
		delete cfg.viewName;
		var viewTPL = ns.ViewTPL[viewName]||this.get(viewName);
		var title = cfg.title || '视图标题';
		delete cfg.title;
		var id = this.prefix + viewName + this.idCounter++;
		baseCfg = {
			id : id,
			xtype : 'panel',
			cls : 'dataview-panel',
			layout : 'ux.center',
			border : false,
			title : title,
			//bodyStyle : 'background: #FDF5E6',//#dfe8f6;
			winCfg : {
				cBtn : false,
				title : title
			},
			items : {
				xtype : 'dataview',
				store : store,
				itemSelector : 'div.dataview-wrap',
				loadingText : '正在加载数据...',
				emptyText : '没有查找到相关数据或关联视图',
				width : '90%',
				tpl : viewTPL
			}
		};
		Hxcy.Util.applyIf(cfg, baseCfg);
		return cfg;
	},
	createUnitTree : function(cfg){
		cfg = typeof cfg=='string' ? {comboId:cfg} : cfg;
		cfg.comboId = cfg.id||cfg.comboId||this.createComboId(cfg);
		var setCombo = this.setCombo;
		var createRecord = this.createRecord;
		var factory = this;
		var id = 'public-unit-tree-'+cfg.comboId;
		if (this.get(id)) {
			return this.get(id);
		}
		var tree = {
			id : id,
			bodyStyle : 'padding:10px;',
			CPTVisible : false,
			layoutConfig : {
				animate : true
			},
			defaults : {
				border : false
			},
			xtype : 'treepanel',
			border : false,
			autoScroll : true,
			CPT : {
				nodeType : 'async',
				text : '单位根',
				uiProvider : Ext.tree.CPTTreeNodeUI
			},
			checkModel : 'single',
			winCfg : {
				width : 300,
				btn0 : false,
				btn1Handler : cfg.handler || function(){
					var tree = this[id].getSource();
					var ids = tree.getChecked('unitId').join(',');
					var texts = tree.getChecked('text').join(',');
					
					if (ids && texts) {
						var rd = createRecord.call(factory, [cfg.valueField||'unitId',cfg.displayField||'unitName'],[ids, texts]);
						setCombo.call(factory, cfg.comboId, rd, ids);
						if(cfg.callback){
							cfg.callback(cfg.comboId, rd, ids, texts);
						}
					}
					Hxcy.CmpMgr.hideWindow();
				}
			},
			loader : new Ext.tree.TreeLoader({
				dataUrl : Hxcy.CPT + '/public/listUnitTreeNode.action',
				baseAttrs : {
					uiProvider : Ext.ux.TreeCheckNodeUI
				},
				listeners : {
					beforeload : function(treeLoader, node) {
						this.baseParams.unitId = node.attributes.unitId||0;
					},
					load : function(loader, node, response) {
						// alert("加载的数据:" + response.responseText);
					},
					loadexception : function(loader, node, response) {
						alert("异常:" + response.statusText);
					}
				}
			}),
			listeners : {
				render : function(tree){
					var ctx = new Hxcy.PageContext(tree, id);
					ctx.registerWnd();
				}
			}
		};
		this.put(id, tree);
		return tree;
	}
}

Hxcy.PageContext = function(source, ctxName){
	this.source = source;
	this.ctxName = ctxName;
}

Hxcy.PageContext.prototype = {
	getSource : function(){
		return this.source;
	}
}

Hxcy.GridContext = function(grid, ctxName){
	this.grid=grid;
	ctxName = ctxName||grid.id
	Hxcy.GridContext.superclass.constructor.call(this, grid, ctxName);
}
Ext.extend(Hxcy.GridContext, Hxcy.PageContext, {
	getGrid : function(){
		return this.grid;
	},
	
	getStore : function(){
		return this.grid.store;
	},
	
	reload : function(options){
		options = options || {};
		if (options.url) {
			this.setTarget(options.url);
		}
		return this.grid.store.reload(options);
	},
	
	load : function(options){
		if (options.url) {
			this.setTarget(options.url);
		}
		return this.grid.store.load(options);
	},
	
	setTarget : function(url){
		this.grid.store.proxy.setUrl(url, true);
		this.grid.store.proxy.api.read.url=url;
	},
	
	getTarget : function(){
		return this.grid.store.proxy.url;
	},
	
	setBaseParams : function(p){
		Ext.apply(this.grid.store.baseParams, p);
	},
	
	getSM : function(){
		return this.grid.selModel;
	},
	getCM : function(){
		return this.grid.colModel;
	},
	getSelected : function(){
		return this.grid.selModel ? this.grid.selModel.getSelected() : null;
	},
	getSelections : function(property, seperator){
		var rds = this.grid.selModel ? this.grid.selModel.getSelections() : null;
		seperator = seperator || ',';
		if (property) {
			var s = [];
			Ext.each(rds, function(rd){
				s.push(rd.get(property));
			});
			return s.join(seperator);
		}
		return rds;
	},
	
	clear : function(){
		var store = this.getStore();
		store.removeAll();
		store.totalLength=0;
		var bar = this.getGrid().getTopToolbar();
		if (bar.pageSize) {
			bar.onLoad(store, null, {});
		}
		bar = this.getGrid().getBottomToolbar();
		if (bar.pageSize) {
			bar.onLoad(store, null, {});
		}
	},
	
	selectRow : function(e){//根据上下文事件来选择表格行
		if (e.getTarget) {
			var row = this.grid.view.findRowIndex(e.getTarget());
			if (row!==false) {
				this.grid.selModel.selectRow(row);
			}
		} else if(typeof e=='number'){
			this.grid.selModel.selectRow(e);//记录索引
		} else if(typeof e=='object'){
			//此处采用ID匹配,而不是采用记录匹配,因为记录匹配太严格
			this.grid.selModel.selectRow(this.grid.store.indexOfId(e.id));
		} else if(Ext.isArray(e)){
			this.grid.selModel.selectRows(e);//记录索引
		}
		return this.getSelected();
	},
	
	activeContextMenu : function(cfg){
		var menu = cfg.menu;
		var callback = cfg.callback;
		var scope = cfg.scope;
		var e = cfg.e;
		e ? this.selectRow(e) : '';//选中上下文记录,如果可能话的
		if(menu.fireEvent('beforeshow', menu) !== false){
			menu.items.each(function(item){
				callback ? callback(item) : '';
			}, scope||this);
			if(e){
				menu.showAt(e.getXY());
				e.stopEvent();
			}
        }
	}
});

Hxcy.FormContext = function(fp, ctxName){
	this.fp = fp;
	ctxName = ctxName || fp.id;
	Hxcy.FormContext.superclass.constructor.call(this, fp, ctxName);
};
Ext.extend(Hxcy.FormContext, Hxcy.PageContext, {
	getForm : function(){
		return this.fp.getForm();
	},
	
	loadRecord : function(record){
		this.fp.getForm().loadRecord(record)
	},
	
	setUrl : function(url){
		this.fp.getForm().url = url;
	},
	
	findField : function(fieldName){
		return this.getForm().findField(fieldName);
	},
	
	setValues : function(values){
		this.getForm().setValues(values);
	},
	
	setDisabled : function(config){
		var form = this.getForm();
		form.items.each(function(field){
			if(field.group){
				if(field.group.indexOf(config.groupName)>=0){
					field.setDisabled(config.disabled);
					if(field.wrap){
						config.disabled ? field.wrap.addClass('x-item-disabled') : field.wrap.removeClass('x-item-disabled');
					}
					if (config.cls) {
						var item = field.getEl().parent('div.x-form-item');
						config.disabled? item.removeClass(config.cls):item.addClass(config.cls);
					}
				} else if(config.other){
					field.setDisabled(!config.disabled);
					if(field.wrap){
						!config.disabled ? field.wrap.addClass('x-item-disabled') : field.wrap.removeClass('x-item-disabled');
					}
				}
			}
		});
	},
	setVisible : function(b, fields){
		fields = typeof fields=='string' ? [fields] : fields;
		for (var index = 0; index < fields.length; index++) {
			var field = this.findField(fields[index]);
			var item = field.getEl().parent('div.x-form-item');
			item.setVisibilityMode(Ext.Element.DISPLAY);
			item.setVisible(b);
		}
	},
	reset : function(record){
		this.fp.getForm().reset();
		if (record) {
			this.loadRecord(record);
		}
	}
});

Hxcy.IFrameContext = function(iframe, ctxName){
	this.iframe = iframe;
	ctxName = ctxName || iframe.id;
	Hxcy.IFrameContext.superclass.constructor.call(this, iframe, ctxName);
};
Ext.extend(Hxcy.IFrameContext, Hxcy.PageContext, {
	getIFrame : function(){
		return this.iframe;
	},
	getWindow : function(){
		return this.iframe.window;
	},
	//获取iframe中的JS对象(即变量)
	getObjectInFrame : function(name){
		var ns = name.split('.');
		var val = this.iframe.window;
		Ext.each(ns, function(item){
			val = val[item];
		});
		return val;
	},
	
	loadUrl : function(url){
		this.iframe.window.location=url;
	}
});

Hxcy.ToolBarContext = function(toolBar, ctxName){
	this.toolBar = toolBar;
	ctxName = ctxName || iframe.id;
	Hxcy.ToolBarContext.superclass.constructor.call(this, toolBar, ctxName);
	var allItems = this.allItems = [];
	var fn = function(item){
		allItems.unshift(item);
		if(item.items && item.doLayout){//如果是一个工具样组件容器
			item.items.each(fn, this);
		} else if(item.menu){//如果是一个具有菜单的组件
			allItems.unshift(item.menu);
			item.menu.items.each(fn, this);
		}
	}
	fn(toolBar);
};
Ext.extend(Hxcy.ToolBarContext, Hxcy.PageContext, {
	getToolBar : function(){
		return this.toolBar;
	},
	
	getAllItems : function(){
		return this.allItems;
	}
});

//===============================以上为非组件的工具类,以下为组件相关类=============================

/**这是一个专门展示内容的窗体,窗体的属性由展示的活动组件来配置*/
Hxcy.Window = Ext.extend(Ext.Window, {
	initComponent : function(){
		Hxcy.Window.superclass.initComponent.call(this);
		Ext.each(this.buttons, function(item){
		item.window = this;
		}, this);
		this.lBtn=this.buttons[0];
		this.cBtn=this.buttons[1];
		this.rBtn=this.buttons[2];
	},
	beforeShow : function(){
		Hxcy.Window.superclass.beforeShow.call(this);
		var activeItem  = this.layout.activeItem;
		if (activeItem.winCfg&&activeItem.winCfg.modal===false) {
			this.mask.hide();
			Ext.getBody().removeClass('x-body-masked');
		} else {
			Ext.getBody().addClass('x-body-masked');
			this.mask.show();
		}
		activeItem.fireEvent('windowbeforeshow', this.layout.activeItem, this);//传两个参数一个是当前被显示的组件自身,另一个是当前窗体
	},
	show : function(animateTarget, cb, scope){
		Hxcy.Window.superclass.show.call(this, animateTarget, cb, scope);
		this.layout.activeItem.fireEvent('windowshow', this.layout.activeItem, this);//传两个参数一个是当前被显示的组件自身,另一个是当前窗体
	},
	afterShow : function(){
		Hxcy.Window.superclass.afterShow.call(this);
		this.layout.activeItem.fireEvent('windowaftershow', this.layout.activeItem, this);//传两个参数一个是当前被显示的组件自身,另一个是当前窗体
	},
	hide : function(animateTarget, cb, scope){
		Hxcy.Window.superclass.hide.call(this, animateTarget, cb, scope);
		var activeItem  = this.layout.activeItem;
		if (activeItem) {
			activeItem.fireEvent('windowhide', this.layout.activeItem, this);//传两个参数一个是当前被显示的组件自身,另一个是当前窗体
		}
	},
	toggleMaximize : function(){
		if (this.disableMax) {
			return;//如果禁止最大化,则不可以在两者间切换
		}
		return this[this.maximized ? 'restore' : 'maximize']();
	},
	
	createCBtnHandler : function(winCfg){
		return function(){
			var wnd = this.window;
			//提交之前的回调
			if (winCfg.CBtnBefore && winCfg.CBtnBefore(wnd, winCfg)===false) {
				return ;
			}
			var defaultCBtnSuccess = function(form, action) {
				Hxcy.Util.msg(action.result['messages'], function(){
					if (winCfg.autoHidden!==false) {
						wnd[wnd.closeAction]();
					}
					if (winCfg.CBtnAfter) {
						winCfg.CBtnAfter(wnd, winCfg);
					}
				});
			};
			var defaultCBtnFailure = function(form, action) {
				var result = action.result;// 这是返回的结果对象
				var msg = result&&result.actionErrors[0] ? result.actionErrors : '服务器内部错误';
				switch (action.failureType) {
					case Ext.form.Action.CLIENT_INVALID:
					//	Hxcy.Util.error('存在非法字段');
						Hxcy.Util.error('填写信息有误！');
						break;
					case Ext.form.Action.CONNECT_FAILURE:
						Hxcy.Util.error('ajax连接失败');
						//Ext.Msg.alert('Failure', 'Ajax communication failed');
						break;
					case Ext.form.Action.SERVER_INVALID:
						Hxcy.Util.error(msg);
						//Ext.Msg.alert('Failure', action.result.msg);
				}
			};
			this.window.layout.activeItem.getForm().submit({
				waitTitle : '请等待',
				waitMsg : "正在处理...",
				//下面对两个方法进行包装主要是为了传递参数,尤其是第三个参数wnd
				success: winCfg.CBtnSuccess ? function(form, action){winCfg.CBtnSuccess(form, action, wnd);winCfg.autoHidden!==false?wnd.hide():''}: defaultCBtnSuccess,
				failure: winCfg.CBtnFailure ? function(form, action){winCfg.CBtnFailure(form, action, wnd);}: defaultCBtnFailure
			});
		};
	},
	
	createRBtnHandler : function(winCfg){
		return function(){
			if (winCfg.RBtnBefore && winCfg.RBtnBefore(this.window, winCfg)===false) {
				return ;
			}
			this.window[this.window.closeAction]();
			if (winCfg.RBtnAfter && winCfg.RBtnAfter(this.window, winCfg)===false) {
				return ;
			}
		};
	},
	
	freshByCfg : function(winCfg){
		this.setSize(winCfg.width||Hxcy.Window.defaultWidth, winCfg.height||Hxcy.Window.defaultHeight);
		this.setTitle(winCfg.title || Hxcy.Window.defaultTitle, winCfg.iconCls || Hxcy.Window.defaultIcon);
		
		//处理按钮自身的显示
		winCfg.lBtn === true ? this.lBtn.show() : this.lBtn.hide();
		winCfg.cBtn === false ? this.cBtn.hide() : this.cBtn.show();
		winCfg.rBtn === false ? this.rBtn.hide() : this.rBtn.show();
		
		//处理按钮的显示文本
		this.lBtn.setText(winCfg.lBtnText||Hxcy.Window.defaultLBtnText);
		this.cBtn.setText(winCfg.cBtnText||Hxcy.Window.defaultCBtnText);
		this.rBtn.setText(winCfg.rBtnText||Hxcy.Window.defaultRBtnText);
		
		//处理按钮的监听器
		winCfg.CBtnBefore||winCfg.CBtnSuccess||winCfg.CBtnFailure ? winCfg.cBtnHandler = this.createCBtnHandler(winCfg) : '';
		winCfg.RBtnBefore||winCfg.RBtnAfter ? winCfg.rBtnHandler = this.createRBtnHandler(winCfg) : '';
		
		this.lBtn.setHandler(winCfg.lBtnHandler? winCfg.lBtnHandler.createDelegate(this.lBtn, this, true) :Hxcy.Window.defaultLBtnHandler);
		this.cBtn.setHandler(winCfg.cBtnHandler? winCfg.cBtnHandler.createDelegate(this.cBtn, this, true) :Hxcy.Window.defaultCBtnHandler);
		this.rBtn.setHandler(winCfg.rBtnHandler? winCfg.rBtnHandler.createDelegate(this.rBtn, this, true) :Hxcy.Window.defaultRBtnHandler);
		
	},
	
	afterShowFreshByCfg : function(winCfg){
		//处理工具栏的显示
		winCfg.toggleHide === false ? this.tools['toggle'].show() : this.tools['toggle'].hide();
		winCfg.maximizeHide === false ? this.tools['maximize'].show()|(this.disableMax=false) : this.tools['maximize'].hide()|(this.disableMax=true);
		winCfg.closeHide === true ? this.tools['close'].hide() : this.tools['close'].show();
		winCfg.resizable === true ? this.resizer.enabled=true : this.resizer.enabled=false;
	},
	
	animHide : function(){
		this.proxy.setOpacity(0.5);
		this.proxy.show();
		var tb = this.getBox(false);
		this.proxy.setBox(tb);
		this.el.hide();
		var b = this.proxy.getBox(false);
		b.x=b.x+b.width/2;
		b.y=b.y+b.height/2;
		//b.right=b.right-b.width/2;
		//b.bottom=b.bottom-b.height/2;
		b.width=b.height=0;
		//b[0]=b.x;b[1]=b.y
		
		b.callback = this.afterHide;
		b.scope = this;
		b.duration = 0.5;
		b.easing = 'easeNone';
		b.block = true;
		b.opacity = 0;
		this.proxy.shift(b);
	},
	
	pop : function(itemCfg) {
		if (itemCfg) {
			var id = Ext.id(itemCfg);
			var c = Ext.getCmp(id);
			if (c && (!this.findById(id))) {
				this.add(c);
			} else if(!c){
				if (this.items && this.items.getCount()>Hxcy.Window.defaultItemCounter) {
					this.items.removeAt(0);//保持窗口中最多只有固定数目的子组件
				}
				this.add(Ext.create(itemCfg, 'panel'));
			}
			var winCfg = itemCfg.winCfg = itemCfg.winCfg || {};//控制winCfg没有配置的情况
			// 这里一定要小心，先设置活动面板，再显示窗体的方法是怎样的
			this.rendered ? this.getLayout().setActiveItem(itemCfg.id) : this.activeItem = itemCfg.id;
			
			this.freshByCfg(winCfg);//显示之前刷新窗体部分配置
			this.show(winCfg.animateTarget||'rsid-window-proxy');
			this.afterShowFreshByCfg(winCfg);//显示之后刷新窗体其它配置
		} else {
			alert('无显示内容');
		}
		return this;
	}
});
Ext.reg('Hxcywindow', Hxcy.Window);

Ext.apply(Hxcy.Window, function(){
	var pub, AUTOID=0;
	var defaultWidth=600,defaultHeight=400, defaultTitle='弹出窗口', defaultIcon='rscls-little-logo';
	var defaultLBtnText='备用',defaultCBtnText='提交',defaultRBtnText='关闭';
	var defaultLBtnHandler=Hxcy.emptyFn;
	
	var defaultCBtnHandler=function(winCfg) {
		var wnd = this.window;
		var defaultCBtnSuccess = function(form, action) {
			Hxcy.Util.msg(action.result['messages'][0], function(){
				wnd.hide();
			});
		};
		var defaultCBtnFailure = function(form, action) {
			switch (action.failureType) {
				case Ext.form.Action.CLIENT_INVALID:
					Hxcy.Util.error('存在非法字段');
					break;
				case Ext.form.Action.CONNECT_FAILURE:
					Hxcy.Util.error('ajax连接失败');
					//Ext.Msg.alert('Failure', 'Ajax communication failed');
					break;
				case Ext.form.Action.SERVER_INVALID:
					Hxcy.Util.error(action.result['actionErrors'][0]||'服务器内部错误');
					//Ext.Msg.alert('Failure', action.result.msg);
			}
		};
		this.window.layout.activeItem.getForm().submit({
			//clientValidation : false,
			waitTitle : '请等待',
			waitMsg : "正在处理...",
			success: defaultCBtnSuccess,
			failure: defaultCBtnFailure
		});
	};
	var defaultRBtnHandler=function(winCfg) {
		this.window[this.window.closeAction]();
	};
	Ext.onReady(function(){
		if(top==window){
			Hxcy.Window.proxy = Ext.getBody().createChild({id:'rsid-window-proxy',tag:'span',style:'widht:1px;height:1px;'});
		}
	});
	pub = {
		defaultItemCounter : 3,
		defaultWindowCounter : 3,
		defaultWidth : defaultWidth,
		defaultHeight : defaultHeight,
		defaultTitle : defaultTitle,
		defaultIcon : defaultIcon,
		defaultLBtnText : defaultLBtnText,
		defaultCBtnText : defaultCBtnText,
		defaultRBtnText : defaultRBtnText,
		defaultLBtnHandler : defaultLBtnHandler,
		defaultCBtnHandler : defaultCBtnHandler,
		defaultRBtnHandler : defaultRBtnHandler,
		windowCache : [],//窗体组件的缓存
		createDefaultCfg : function(){
			var genId = AUTOID++
			return {
				id : 'rsid-pop-window-auto-id-'+genId,
				xtype : 'Hxcywindow',
				width : defaultWidth,
				height : defaultHeight,
				title : defaultTitle,
				iconCls : defaultIcon,
				//minimizable : true,
				collapsible : true,
				maximizable : true,
				constrain : true,
				resizable : true,
				modal : true,
				closeAction : "hide",
				layout : "card",
				activeItem : 0,
				defaults : {
					border : false,
					bodyBorder : false
				},
				buttons : [{
					id : "rsid-pop-window-left-button-" + +genId,
					text : defaultLBtnText,
					handler : defaultLBtnHandler
				}, {
					id : "rsid-pop-window-center-tutton-" + +genId,
					text : defaultCBtnText,
					handler : defaultCBtnHandler
				}, {
					id : "rsid-pop-window-right-tutton-" + +genId,
					text : defaultRBtnText,
					handler : defaultRBtnHandler
				}]
			}
		},
		getNextAvailable : function(){
			var nextAvailable;
			Ext.each(Hxcy.Window.windowCache, function(wnd){
				if(!(wnd.isVisible())){
					nextAvailable = wnd;
					return false;
				}
			});
			if (nextAvailable) {
				return nextAvailable;
			}
			nextAvailable = new Hxcy.Window(Hxcy.Window.createDefaultCfg());
			Hxcy.Window.windowCache.push(nextAvailable);
			return nextAvailable;
		},
		pop : function(itemCfg){
			var wnd = null;
			if (itemCfg.winCfg&&itemCfg.winCfg.modal===false) {//如果是非模式窗体,则不进行缓存,且关闭后直接销毁
				if (Ext.getCmp(Ext.id(itemCfg))) {//说明当前当前正处于显示状态
					wnd = Ext.WindowMgr.get(Ext.getCmp(Ext.id(itemCfg)).ownerCt.id);
				} else {
					wnd = new Hxcy.Window(Ext.applyIf({closeAction:'close'}, Hxcy.Window.createDefaultCfg()));
				}
			} else {
				wnd = Hxcy.Window.getNextAvailable();//如果是模式窗体则进行缓存
			}
			wnd.pop(itemCfg);
			this.currentWindow = wnd;
			this.free();//释放窗体;
			return wnd
		},
		free : function(){//将窗口实体数据释放到额定数
			var cache=Hxcy.Window.windowCache;
			while(Hxcy.Window.defaultWindowCounter<cache.length){
				var wnd = cache.shift();
				wnd.close();//释放窗体
			}
		},
		clear : function(){//清除所有的窗体对象
			Ext.each(Hxcy.Window.windowCache, function(wnd){
				wnd.close();
			});
			Hxcy.Window.windowCache.length=0;
		},
		getTop : function(){
			return Ext.WindowMgr.getActive();
		},
		moveProxyTo : function(x, y){
			Hxcy.Window.proxy.setXY([x, y]);
		}
	};
	return pub;
}());

Hxcy.pop = Hxcy.Window.pop.createDelegate(Hxcy.Window);//弹出窗口的快捷方式
Hxcy.getTopWin = Hxcy.Window.getTop.createDelegate(Hxcy.Window);//弹出窗口的快捷方式

Hxcy.TabPanel = Ext.extend(Ext.TabPanel, {
	//closeAction : 'hide',
	showTab : function(itemCfg) {
		if (itemCfg) {
			if (!this.findById(itemCfg.id)) {
				var t = this.add(itemCfg);
			}
			this.setActiveTab(t || itemCfg.id);
		} else {
			alert('无显示内容');
		}
	}
});
Ext.reg('Hxcytabpanel', Hxcy.TabPanel);

//下面的处理有些不好,它的限定只针对全局唯一的Hxcy.TabPanel实例,并且它的id是固定的
Hxcy.showTab = function(itemCfg){
	Hxcy.TabPanel = Hxcy.TabPanel || Ext.getCmp('contentWrapper')||top.Ext.getCmp('contentWrapper');
	Hxcy.TabPanel.showTab(itemCfg);
};

//下面是一个简单的iframe组件
Hxcy.IFrame = Ext.extend(Ext.BoxComponent, {
	//表示第一次是否进行遮盖
	firstLoading : true,
	
	initComponent :function(){
		this.tagCfg = this.tagCfg||{};
		Hxcy.IFrame.superclass.initComponent.call(this);
		this.addEvents(
			'beforeload',
			'load',
			'unload'
		);
		this.src = this.src||this.url;
	},
	onRender : function(ct, position) {
		var iframeWrapper = Ext.get(this.el);
		if(!iframeWrapper){
			Ext.applyIf(this.tagCfg, {
				tag : 'iframe',
				id : this.id + '-iframe',
				name : this.id + '-iframe',
				cls : 'rscls-iframe-body',
				frameBorder : 0,
				src : this.url,
				onreadystatechange : this.onReadyStateChange.createDelegate(this)
			});
			var div = document.createElement('div');
			Ext.DomHelper.overwrite(div, this.tagCfg);
			this.iframeEl=Ext.get(div.firstChild);
			this.el = this.iframeEl.wrap({id:this.id, cls:this.border===true ? 'rscls-mask-ct rscls-mask-ct-border' : 'rscls-mask-ct'});
		} else {//这种情况一般需要在body中配置类似结构<div class="x-hidden" id="content"><iframe src="/kpb/Hxcy/home/home.jsp"></iframe></div>
			iframeWrapper.addClass(this.border===true ? 'rscls-mask-ct rscls-mask-ct-border' : 'rscls-mask-ct');
			this.iframeEl=Ext.get(iframeWrapper.dom.firstChild);
			this.iframeEl.addClass('rscls-iframe-body');
			this.iframeEl.dom.frameBorder=0;
			this.iframeEl.dom.src=this.url;
			this.iframeEl.on('onreadystatechange',this.onReadyStateChange.createDelegate(this));
		}
		this.initEvent();//在初始化事件之前不要将结点挂接到当前文档中,因为这会导致iframe中的内容会立即加载
		
		Hxcy.IFrame.superclass.onRender.call(this, ct, position);
		
		this.el.show();
		this.window = self.frames[this.iframeEl.id];
		//注意:这个成员只具有一次性的,如果加载地址改变,这个对象就不存在了,所还是使用this.window.document最安全
		//this.document = this.window.document;
	},
	
	initEvent : function(){
		this.mon(this.iframeEl, {
			scope : this,
			'click' : this.onClick,
			'load': this.onLoad,
			'unload' : this.unLoad,
			'readystatechange' : this.onReadyStateChange.createDelegate(this)//readystatechange对非IE浏览器没有作用
		});
		if (this.firstLoading) {
			this.ownerCt.on('afterlayout', function(){//此处用afterlayout替换本来的render事件
				this.onLoading();//readystatechange对一次加载无法拦截,这里用afterlayout替换,注意:只有布局后遮盖才有意义
			}, this, {single : true});
		}
	},
	onReadyStateChange : function(){ 
	    //这个地方不要使用this.document
		if(this.window.document== null||this.window.document.readyState=='loading'){
			this.onLoading();
		}
	},
	onLoading : function(){
		this.el.mask('正在加载中...', 'rscls-loading-sun');
		this.fireEvent('beforeload', this);
	},
	onClick : function(e, iframedom){
		alert(e.getXY());
	},
	onLoad : function(e, iframedom){
		var el = this.el;
		if(el.child('div[className*=rscls-loading-sun]')){
			el.child('div[className*=rscls-loading-sun]').animate({
				opacity : {to:0, from:1}
			},0.35, null, 'easeout');
			
			el.child('div[className*=ext-el-mask]').animate({
				opacity : {to:0, from:0.3}
			},0.35, function(){
				el.unmask();
			}, 'easeout');
		}
		
		this.fireEvent('load', this, e);
	},
	unLoad : function(e, iframedom){
		this.fireEvent('unload', this, e);
	},
	loadUrl : function(url){
		if(this.window){
			this.window.location=url;
		}
	}
});
Ext.reg('Hxcyiframe', Hxcy.IFrame);

Hxcy.BoxButton = Ext.extend(Ext.Button, {
	initComponent : function(){
		Ext.BoxComponent.superclass.initComponent.call(this);
		if (!Hxcy.BoxButton.buttonTemplate) {
			Hxcy.BoxButton.buttonTemplate = new Ext.Template(
			'<table border="0" cellpadding="0" cellspacing="0" class="x-btn {3}"><tbody class="{4}"><tr>',
			'<td class="x-btn-left"><i>&#160;</i></td>',
			'<td class="x-btn-center"><em unselectable="on"><button class="x-btn-text {2}" type="{1}">&#160</button>{0}</em></td>',
			'<td class="x-btn-right"><i>&#160;</i></td>', "</tr></tbody></table>");
			Hxcy.BoxButton.buttonTemplate.compile();
		}
		this.template = Hxcy.BoxButton.buttonTemplate;
	}
});
Ext.reg('Hxcyboxbutton', Hxcy.BoxButton);

Hxcy.OuterLink = Ext.extend(Ext.Button, {
	buttonSelector : 'a:first-child',
	initComponent : function(){
		Ext.BoxComponent.superclass.initComponent.call(this);
		if (!Hxcy.OuterLink.buttonTemplate) {
			Hxcy.OuterLink.buttonTemplate = new Ext.Template('<div class="x-btn rscls-outer-link {3}"><em><a class="x-btn-text {2}">&#160</a>{0}</em></div>');
			Hxcy.OuterLink.buttonTemplate.compile();
		}
		this.template = Hxcy.OuterLink.buttonTemplate;
	}
});
Ext.reg('Hxcyouterlink', Hxcy.OuterLink);

Hxcy.InnerLink = Ext.extend(Ext.Button, {
	buttonSelector : 'a:first-child',
	initComponent : function(){
		Ext.BoxComponent.superclass.initComponent.call(this);
		if (!Hxcy.InnerLink.buttonTemplate) {
			Hxcy.InnerLink.buttonTemplate = new Ext.Template('<div class="x-btn rscls-inner-link {3}"><a class="x-btn-text {2}">{0}</a></div>');
			Hxcy.InnerLink.buttonTemplate.compile();
		}
		this.template = Hxcy.InnerLink.buttonTemplate;
	}
});
Ext.reg('Hxcyinnerlink', Hxcy.InnerLink);

Hxcy.TableFormLayout = Ext.extend(Ext.layout.TableLayout, {
	monitorResize : false,
	labelSeparator : ':',
	
	subContainerDefault : {
		layoutConfig: {
			tableAttrs : {align:'center', width:'100%', style:'table-layout : fixed;'},
			columns: 2
		}
	},
	
	onLayout : function(ct, target){
		Hxcy.TableFormLayout.superclass.onLayout.call(this, ct, target);
		/*var items = ct.items;
		items.each(function(item){
			var td = item.el.parent('td.x-table-layout-cell');
			alert(td.getWidth(true)+'TTT'+td.getHeight(true));
			if(item.fit===true){
				item.setSize(td.getWidth(true), td.getHeight(true));
			}
		});*/
	},
	
	setContainer : function(ct){
		Hxcy.TableFormLayout.superclass.setContainer.call(this, ct);
		if(ct.labelAlign){
			ct.addClass('x-form-label-'+ct.labelAlign);
		}
		
		if(ct.hideLabels){
			this.labelStyle ="display:none";
			this.elementStyle ="padding-left:0;";
			this.labelAdjust = 0;
		}else{
			this.labelSeparator = ct.labelSeparator || this.labelSeparator;
			ct.labelWidth = ct.labelWidth || 100;
			if(typeof ct.labelWidth == 'number'){
				var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5);
				this.labelAdjust = ct.labelWidth+pad;
				this.labelStyle ="width:"+ct.labelWidth+"px;";
				this.elementStyle ="padding-left:"+(ct.labelWidth+pad)+'px;';
			}
			if(ct.labelAlign == 'top'){
				this.labelStyle ="width:auto;";
				this.labelAdjust = 0;
				this.elementStyle = "padding-left:0;";
			}
		}
	},
	getNextCell : function(c){
		//获取下一个单元格的行列值
		var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
		var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
		for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
			if(!this.cells[rowIndex]){
				this.cells[rowIndex] = [];
			}
			for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
				this.cells[rowIndex][colIndex] = true;
			}
		}
		var tdAttr = c.tdAttr||this.tdAttr ||{};
		if(c.cellId){
			tdAttr.id = c.cellId;
		}
		var cls = 'x-table-layout-cell';
		if(c.cellCls){
			cls += ' ' + c.cellCls;
		}
		tdAttr.cls = cls;
		if(c.colspan){
			tdAttr.colSpan = c.colspan;
		}
		if(c.rowspan){
			tdAttr.rowSpan = c.rowspan;
		}
		tdAttr.tag='td';
		var td = Ext.DomHelper.append( this.getRow(curRow), tdAttr);
		return td;
	},
	renderItem : function(c, position, target){
		if(c && !c.rendered ){
			if(this.extraCls){
				var t = c.getPositionEl ? c.getPositionEl() : c;
				t.addClass(this.extraCls);
			}
			
			if (c.inTable!==false&&(c.isFormField || c.fieldLabel) && c.inputType != 'hidden') {
				//如果是一个表单域
				target = this.getNextCell(c);
				var args = this.getTemplateArgs(c);
				this.fieldTpl.append(target, args);
				//前面步骤主要是在包装一个表单域,下面是在一个包装中嵌入(渲染)真正的表单域
				//'x-form-el-'+c.id是在包装模板中指定的dom容器,对于表单的包装体主要需要了解两个类,x-form-item是对整个表单域的包装
				//包括表单标签在内;x-form-element是对表单域直接容器,即是表单元素的直接上级容器元素;x-form-item-label是表单标签类
				c.render('x-form-el-'+c.id);
			} else if (c.inTable===true) {//在这里进行这样的处理主要为了在表单中加,一些容器,容器
				Hxcy.Util.applyIf(c, this.subContainerDefault);
				target = this.getNextCell(c);
				c.render(target);
			} else {//在这里进行这样的处理主要为了在表单中加,一些容器,容器
				Hxcy.Util.applyIf(c, this.subContainerDefault);
				c.render(target);
			}
		}
	},
	getTemplateArgs: function(field) {
		var noLabelSep = !field.fieldLabel || field.hideLabel;
		return {
			id: field.id,
			label: field.fieldLabel,
			labelStyle: field.labelStyle||this.labelStyle||'',
			elementStyle: field.elementStyle||this.elementStyle||'',
			labelSeparator: noLabelSep ? '' : (typeof field.labelSeparator == 'undefined' ? this.labelSeparator : field.labelSeparator),
			itemCls: (field.itemCls||this.itemCls||this.container.itemCls||'') + (field.hideLabel ? ' x-hide-label' : ''),
			clearCls: field.clearCls || 'x-form-clear-left'
		};
	}
});
Ext.Container.LAYOUTS['tableform'] = Hxcy.TableFormLayout;

Hxcy.AccordionLayout = Ext.extend(Ext.layout.AccordionLayout, {
	beforeExpand : function(p, anim){
		var ai = this.activeItem;
		if(ai){
			if(this.sequence){//如果配置sequence为true应该表示:先折叠当前的活动面板,再展开p,否则这两个动作应该是同时进行的
				delete this.activeItem;
				if (!ai.collapsed){
					ai.collapse({callback:function(){
						p.expand(anim || true);
					}, scope: this});
					return false;//阻止p自身的展开动作
				}
			}else{
				ai.collapse(this.animate);//这是与面板紧密相关的操作,不是一般的子组件所具有的
			}
		}
		this.activeItem = p;
		if(this.activeOnTop){
			p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
		}
		this.layout();
	}
});
Ext.Container.LAYOUTS['Hxcyaccordion'] = Hxcy.AccordionLayout;

Hxcy.SingleSearch = function(config) {
	Hxcy.SingleSearch.superclass.constructor.call(this, config);
};

Ext.extend(Hxcy.SingleSearch, Ext.BoxComponent, {
	/**
	 * @cfg {String} 显示在菜单按钮上的文字
	 */
	 searchText:'查询',

	/**
	 * @cfg {String} searchTipText 当前鼠标放在框上的时候提示的文字
	 */ 
	searchTipText:'输入需要查询的文字然后按钮enter键',

	/**
	 * @cfg {String} selectAllText 菜单中选择所有选项的文字
	 */
	selectAllText:'选择所有',

	/**
	 * @cfg {String} iconCls Icon class for menu button (defaults to icon-magnifier)
	 */
	iconCls:'icon-magnifier',

	/**
	 * @cfg {String/Array} 初始化时哪些选项是被选中的,默认是所有
	 */
	menuItems:[],
	
	//lastFields:[],
	
	/**
	 * @cfg {String/Array} 初始化时哪些选项是被选中的,默认是所有
	 */
	checkIndexes:'all',

	/**
	 * @cfg {Boolean} showSelectAll 决定是在在菜单项中出现选择所有的菜单(默认为true)
	 */
	showSelectAll:true,

	/**
	 * @cfg {String} menuStyle 合法的值有'checkbox'与'radio'. 
	 * 如果为radio则菜单中一次只选择一个条目,此时选择所有的菜单将自动关闭.
	 */
	menuStyle:'checkbox',

	/**
	 * @cfg {Number} minChars 这是发起请求的一个阀值,如果此选项被配置,则当前字符数据操作这个值将会自动发起请求.
	 * 如果没有定义,则在trigger域将会显示一个放大镜图标,你需要点击这个图标或按钮enter键才能起动查询;如果此选项定义过,
	 * 则当前字符的输入个数为0或超过设置值,将自动发起请求,并且放在镜图标将不会再显示出来
	 */

	/**
	 * @cfg {String} minCharsTipText 最小字符数提示文字
	 */
	minCharsTipText:'至少需要输入{0}个字符',

	/**
	 * @cfg {Array} readonlyIndexes 在菜单中被禁止修改的条目
	 */

	/**
	 * @cfg {Number} width trigger输入框的宽度 (默认100)
	 */
	width:100,

	/**
	 * @cfg {Object} paramNames 字段参数名与查询参数名(默认为{fields:'fields', query:'query'}
	 */
	paramNames: {
		fields:'fields',
		query:'query'
	},

	/**
	 * @cfg {String} shortcutKey 输入框获取焦点的快捷键(默认为r = Sea_r_ch). 空字符表示禁用快捷键
	 */
	shortcutKey:'r',

	/**
	 * @cfg {String} shortcutModifier 快捷键的辅助键. 合法的值有: alt, ctrl, shift (默认为alt)
	 */
	shortcutModifier:'alt',

	/**
	 * @cfg {Number} minLength 在可以进行查询之前强制需要输入的字符数
	 */
	
	autoEl : {tag:'div', cn:{tag:'table', cn:{tag:'tr', cn:[{tag:'td', cls:'rscls-single-search-menu-ct'}, {tag:'td', cls:'rscls-single-search-field-ct'}]}}},
	
	onResize : function(w, h){
		Hxcy.SingleSearch.superclass.onResize.call(this, w, h);
		if(typeof w == 'number'){
			this.field.el.setWidth(w - this.field.trigger.getWidth()-this.menuEl.getWidth()-6);
			this.field.wrap.setWidth(w -this.menuEl.getWidth()-4);
		}
	},
	
	onRender : function(ct, position){
		Hxcy.SingleSearch.superclass.onRender.call(this, ct, position);
		this.menuEl = this.el.child('.rscls-single-search-menu-ct');
		this.fieldEl = this.el.child('.rscls-single-search-field-ct');
		
		this.menu = this.createMenu();
		this.menuButton = new Ext.Button({
			renderTo : this.menuEl,
			text:this.searchText,
			cls : 'rscls-single-search-btn',
			menu:this.menu,
			iconCls:this.iconCls
		});
		
		this.field = new Ext.form.TwinTriggerField({
			width:this.width,
			selectOnFocus:undefined === this.selectOnFocus ? true : this.selectOnFocus,
			trigger1Class:'x-form-clear-trigger',
			trigger2Class:this.minChars ? 'x-hide-display' : 'x-form-search-trigger',
			onTrigger1Click:this.onTriggerClear.createDelegate(this),
			onTrigger2Click:this.minChars ? Ext.emptyFn : this.onTriggerSearch.createDelegate(this),
			minLength:this.minLength
		});
		//绑定相关的事件
		this.field.on('render', function() {
			this.field.el.dom.qtip = this.minChars ? String.format(this.minCharsTipText, this.minChars) : this.searchTipText;

			if(this.minChars) {
				this.field.el.on({scope:this, buffer:300, keyup:this.onKeyUp});
			}

			var map = new Ext.KeyMap(this.field.el, [{
				 key:Ext.EventObject.ENTER,
				 scope:this,
				 fn:this.onTriggerSearch
			},{
				 key:Ext.EventObject.ESC,
				 scope:this,
				 fn:this.onTriggerClear
			}]);
			map.stopEvent = true;
		}, this, {single:true});
		
		if(this.shortcutKey && this.shortcutModifier) {
			var shortcutEl = ct;
			var shortcutCfg = [{
				 key:this.shortcutKey,
				 scope:this,
				 stopEvent:true,
				 fn:function() {
					this.focus();
				}
			}];
			shortcutCfg[0][this.shortcutModifier] = true;
			this.keymap = new Ext.KeyMap(shortcutEl, shortcutCfg);
		}
		
		this.field.render(this.fieldEl);
	},
	
	createMenu : function(){
		var menu = new Ext.menu.Menu();
		if(this.showSelectAll && 'radio' !== this.menuStyle) {
			menu.add(new Ext.menu.CheckItem({
				 text:this.selectAllText,
				 checked:!(this.checkIndexes instanceof Array),
				 hideOnClick:false,
				 handler:function(item) {
					var checked = ! item.checked;
					item.parentMenu.items.each(function(i) {
						if(item !== i && i.setChecked && !i.disabled) {
							i.setChecked(checked);
						}
					});
				}
			}),'-');
		}
		
		var group = undefined;
		if('radio' === this.menuStyle) {
			group = 'g' + (new Date).getTime();	
		}
		//处理所有字段
		Ext.each(this.menuItems, function(item) {
			menu.add(new Ext.menu.CheckItem({
				 text:item.text,
				 name:item.name,
				 hideOnClick:'radio' === this.menuStyle,
				 group:group,
				 checked:'all' === this.checkIndexes||item.checked
			}));
		}, this);
		//处理被选择的字段
		if(this.checkIndexes instanceof Array) {
			Ext.each(this.checkIndexes, function(name) {
				var itm = menu.items.find(function(item) {
					return item.name === name;
				});
				if(itm) {
					itm.setChecked(true, true);
				}
			}, this);
		}
		//处理禁止修改的字段
		if(this.readonlyIndexes instanceof Array) {
			Ext.each(this.readonlyIndexes, function(name) {
				var itm = menu.items.find(function(item) {
					return item.name === name;
				});
				if(itm) {
					itm.disable();
				}
			}, this);
		}
		return menu;
	},

	/**
	 * 处理trigger输入框的按键事件
	 * @private
	 */
	onKeyUp:function() {
		var length = this.field.getValue().toString().length;
		if(0 === length || this.minChars <= length) {
			this.onTriggerSearch();
		}
	},
	/**
	 * private 处理清除按钮事件
	 */
	onTriggerClear:function() {
		if(this.field.getValue()) {
			this.field.setValue('');
			this.field.focus();
			this.onTriggerSearch();
		}
	},
	/**
	 * private 处理查询按钮事件
	 */
	onTriggerSearch:function() {
		if(!this.field.isValid()) {
			return;
		}
		var val = this.field.getValue();
		var store = this.store;
		var lastOpt = (store.lastOptions = store.lastOptions ||{});
		lastOpt.params = lastOpt.params || {};
		
		lastOpt.params[store.paramNames.start] = 0;
		lastOpt.params[store.paramNames.limit] = this.limit || Hxcy.LIMIT;

		var fields = [];
		this.menu.items.each(function(item) {
			if(item.checked&&item.name) {
				fields.push(item.name);
			}
		});
		
		//清理参数
		Ext.each(this.menuItems, function(item){
			var name = item.name;
			delete(store.baseParams[name]);
			if (lastOpt && lastOpt.params) {
				delete(lastOpt.params[name]);
			}
		});
		//重新设置参数
		Ext.each(fields, function(name){
			store.baseParams[name] = val;
		});
		
		this.store.reload();
	},
	/**
	 * @param {Boolean} true 设置查询输入框的启用/禁用
	 */
	setDisabled:function() {
		this.setDisabled.apply(this.field, arguments);
	},
	/**
	 * 启用Trigger查询输入框架
	 */
	enable:function() {
		this.setDisabled(false);
	},
	/**
	 * 禁用Trigger查询输入框架
	 */
	disable:function() {
		this.setDisabled(true);
	}
});
Ext.reg('singlesearch', Hxcy.SingleSearch);

Hxcy.SortForm = function(config) {
	//这里属性的复制必须在超类的构造函数之前调用,其中的items属性需要在构造方法中被使用
	Hxcy.SortForm.superclass.constructor.call(this, config);
};

Ext.extend(Hxcy.SortForm, Ext.form.FormPanel, {
	initComponent : function(){
		//在这里组织临时变量
		var listHeight = this.listHeight||350;//列表高度默认为350,此时窗体假设为450*450
		var listWidth = this.listWidth ? this.listWidth+'px' : '250px';//列表默认宽度为250px;
		var introText = this.introText || '没有说明';
		var dataIndex = this.dataIndex || 'unit_name';
		var sequenceName = this.sequenceName || 'ILC';//向后台传递值的名称
		
		//这个方法在超类方法之前执行很重要
		Ext.apply(this, {
			layout : 'tableform',
			ctCls : this.ctCls ? this.ctCls+' rscls-sort-ct' : 'rscls-sort-ct',
			defaults:{
				inTable:true
			},
			layoutConfig: {
				 tableAttrs : {align:'center', width:'100%', style:'table-layout : fixed;'},
				 columns: 2
			},
			items : [{
				autoScroll : true,
				rowspan : 3,
				bodyStyle : 'padding:10px;',
				height : listHeight,
				tdAttr : {style:'width:'+listWidth+';padding:0px;'},
				items : [{
					xtype : 'listview',
					fit : true,
					store: this.store,//需要在用户配置
					disableHeaders : true,
					hideHeaders : true,
					//multiSelect: true,
					singleSelect : true,
					emptyText: '没有可排序的选项',
					columns: [{
						header: '',//不需要标头
						dataIndex: dataIndex//需要在用户配置
					}]
				}, {
					name : sequenceName,
					xtype : 'hidden',
					idName : this.idName,
					store : this.store
				}]
			}, {
				tdAttr : {style:'font-size:12px;border:1px solid;color:red;text-align:center;'},
				xtype : 'tbtext',
				text : introText
			}, {
				iconCls : 'rscls-move-up',
				tdAttr : {style:'vertical-align:bottom;padding-bottom:30px;', align:'center'},
				scale: 'medium',
				text : '上  移',
				xtype : 'button',
				handler : this.onUp.createDelegate(this)
			}, {
				iconCls : 'rscls-move-down',
				tdAttr : {style:'vertical-align:top;padding-top:30px;', align:'center'},
				scale: 'medium',
				text : '下  移',
				xtype : 'button',
				handler : this.onDown.createDelegate(this)
			}]
	
		});
		Hxcy.SortForm.superclass.initComponent.call(this);
	},
	
	onRender : function(ct, position){
		Hxcy.SortForm.superclass.onRender.call(this, ct, position);
		this.listView = this.items.itemAt(0).items.itemAt(0);
		this.hiddenField = this.items.itemAt(0).items.itemAt(1);
		this.store.on('load', function(){
			this.hiddenField.setValue(this.getValue());
		}, this);
	},
	
	getValue : function(){
		var ids = this.store.collect(this.idName);
		return ids.join(',');
	},

	onUp : function(){
		var selected = this.listView.getSelectedIndexes();
		if(!selected||selected.length==0){
			return;//这里可以添加警告逻辑,没有选择
		}
		var rdIndex = selected[0]
		if (rdIndex==0) {
			return;//这里可以添加警告逻辑,到顶
		}
		var rd = this.store.getAt(rdIndex);
		this.store.insert(rdIndex-1, [rd]);
		this.listView.refresh();
		this.listView.select(rdIndex-1);
		this.hiddenField.setValue(this.getValue());
	},
	onDown : function(){
		var selected = this.listView.getSelectedIndexes();
		if(!selected||selected.length==0){
			return;//这里可以添加警告逻辑,没有选择
		}
		var rdIndex = selected[0]
		if (rdIndex>=this.store.getCount()-1) {
			return;//这里可以添加警告逻辑,到底
		}
		var rd = this.store.getAt(rdIndex);
		this.store.insert(rdIndex+1, [rd]);
		this.listView.refresh();
		this.listView.select(rdIndex+1);
		this.hiddenField.setValue(this.getValue());
	}
});
Ext.reg('sortform', Hxcy.SortForm);


Hxcy.SearchTree = function(config) {
	//这里属性的复制必须在超类的构造函数之前调用,其中的items属性需要在构造方法中被使用
	Hxcy.SearchTree.superclass.constructor.call(this, config);
};

Ext.extend(Hxcy.SearchTree, Ext.TabPanel, {
	/**
	 * @cfg {String} treeUrl 这是展开树结点的请求地址,树每展开一个结点都会请求一个地址,并返回子结点的结果
	 */
	
	/**
	 * @cfg {String} searchUrl 这是查询子组件请求的地址,这个地址最终将会生成一个store,如果配置了searchStore
	 * 就不需要配置此属性,还要注意此属性将优先于searchStore(还未实现)
	 */
	
	/**
	 * @cfg {String} searchStore 查询子组件的数据支持
	 */
	
	/**
	 * @cfg {String} treePathUrl 在这个复合组件中的右侧是一个查询组件,在它查询到一个结果后,如果切换到树组件上将树
	 * 展开时必须提供被展开结点的树路径,此地址就是用来返回树路径的
	 */
	
	/**
	 * @cfg {Number} pageSize 执行查询时的页面记录大小
	 */
	
	/**
	 * @cfg {Number} searchWidth 将查询框放在工具栏上的时候,此参数决定其宽度
	 */
	
	/**
	 * @cfg {Bool} searchAsToolBar 是否将查询框放在工具栏上
	 */
	
	
	initComponent : function(){
		//外部的配置
		this.treeCfg = this.treeCfg || {};
		this.searchCfg = this.searchCfg || {};
		this.viewCfg = this.viewCfg || {};
		this.pageBar = this.pageBar || new Ext.PagingToolbar({
			pageSize : this.pageSize||Hxcy.LIMIT,
			store : this.searchStore,
			paramNames : {
				start : 'page.start',
				limit : 'page.limit'
			}
		});
		this.rightCfg = this.rightCfg || {};
		//以下为默认配置
		var treeCfg = {
			title : '树结构',
			xtype :'treepanel',
			autoScroll: true,
			animate: true,
			enableDD: false,
			containerScroll: true,
			CPTVisible : false,
			border: false,
			dataUrl: this.treeUrl,

			CPT: {
				nodeType: 'async',
				text: '根结点',
				cls : 'rscls-CPT-node',
				iconCls : 'icon-CPT',
				draggable: false,
				id: -1
			}
		};
		
		var searchCfg = {
			anchor : '99%',
			xtype : 'singlesearch',
			width : this.searchWidth||180,
			limit : this.limit||this.pageBar.pageSize||Hxcy.LIMIT,
			minCharsTipText:'至少需要输入{0}个字符,双击单位名称可转到单位树',
			menuStyle : 'radio',
			//minChars : 1,
			store : this.searchStore,
			menuItems : [{text:this.searchLabel||'机构名称',name:this.searchName||'unit_name'}]
		};
		
		var viewCfg = {
			xtype : 'listview',
			store: this.searchStore,
			disableHeaders : true,
			hideHeaders : true,
			singleSelect: true,
			emptyText: this.emptyText||'没有符合要求的机构',
			columns: [{
				header: this.searchLabel||'机构名称',
				dataIndex: this.searchName||'unit_name'
			}]
		};
		
		Hxcy.Util.applyIf(this.searchCfg, searchCfg);
		Hxcy.Util.applyIf(this.viewCfg, viewCfg);
		Hxcy.Util.applyIf(this.treeCfg, treeCfg);
		
		//右侧的搜索配置
		var rightCfg = {
			title : '机构搜索',
			autoScroll : true,
			bbar : this.pageBar,
			items : [this.viewCfg]
		};
		
		if (this.searchAsToolBar===false) {
			rightCfg.items.unshift(this.searchCfg);
			rightCfg.layout = 'anchor';
		} else {
			rightCfg.tbar = {
				items : [this.searchCfg]
			};
		}
		
		Hxcy.Util.applyIf(this.rightCfg, rightCfg);
		
		this.activeItem = 0,
		this.ctCls = this.ctCls ? this.ctCls+' rscls-search-tree-ct' : 'rscls-search-tree-ct';
		this.items = [this.treeCfg, this.rightCfg];
		
		Hxcy.SearchTree.superclass.initComponent.call(this);
		
		this.treePanel = this.items.itemAt(0);
		this.listView = this.items.itemAt(1).items.itemAt(0);
		//this.singleSearch = this.items.itemAt(1).items.itemAt(0);
		
		this.listView.treePanel = this.treePanel;
		this.listView.tabPanel = this;
		
		//绑定事件
		this.listView.on('click', this.onViewClick);
	},
	
	onViewClick : function(dv, idx, node, e){
		var rd = this.store.getAt(idx);
		var tabpanel = this.tabPanel;
		var tree = this.treePanel;
		var params = {};
		params[tabpanel.idName||tabpanel.idKey] = rd.get(tabpanel.idKey||'id');
		Hxcy.request({
			url: tabpanel.treePathUrl,
			success : function(rst, msgs){
				tree.collapseAll();
				tabpanel.setActiveTab(0);
				var result = tree.expandPath(rst.messages[0], null, function(success, oLastNode){
					success ? oLastNode.ensureVisible() : '';
				});
				tree.selectPath(rst.messages[0]);
			},
			params: params
		});
	}
});
Ext.reg('searchtree', Hxcy.SearchTree);

Hxcy.SearchView = function(config) {
	//这里属性的复制必须在超类的构造函数之前调用,其中的items属性需要在构造方法中被使用
	Hxcy.SearchView.superclass.constructor.call(this, config);
};

Ext.extend(Hxcy.SearchView, Ext.Panel, {
	/**
	 * @cfg {String} searchStore 查询子组件的数据支持
	 */
	
	/**
	 * @cfg {Number} pageSize 执行查询时的页面记录大小
	 */
	
	/**
	 * @cfg {Number} searchWidth 将查询框放在工具栏上的时候,此参数决定其宽度
	 */
	
	/**
	 * @cfg {Bool} searchAsToolBar 是否将查询框放在工具栏上
	 */
	initComponent : function(){
		//外部的配置
		this.searchCfg = this.searchCfg || {};
		this.viewCfg = this.viewCfg || {};
		this.pageBar = this.pageBar || new Ext.PagingToolbar({
			pageSize : this.limit || this.pageSize||Hxcy.LIMIT,
			store : this.searchStore,
			paramNames : {
				start : 'page.start',
				limit : 'page.limit'
			}
		});
		this.baseCfg = this.baseCfg || {};
		//以下为默认配置
		var searchCfg = {
			anchor : '99%',
			xtype : 'singlesearch',
			width : this.searchWidth||180,
			limit : this.limit||this.pageBar.pageSize||Hxcy.LIMIT,
			minCharsTipText:'至少需要输入{0}个字符,双击单位名称可转到单位树',
			menuStyle : 'radio',
			//minChars : 1,
			store : this.searchStore,
			menuItems : [{text:this.searchLabel||'机构名称',name:this.searchName||'unit_name'}]
		};
		
		var columns = this.columns || [{
				header: this.searchLabel||'机构名称',
				dataIndex: this.searchName||'unit_name'
			}];
		
		var viewCfg = {
			xtype : 'listview',
			store: this.searchStore,
			disableHeaders : true,
			hideHeaders : true,
			singleSelect: true,
			emptyText: this.emptyText||'没有符合要求的机构',
			columns: columns
		};
		
		Hxcy.Util.applyIf(this.searchCfg, searchCfg);
		Hxcy.Util.applyIf(this.viewCfg, viewCfg);
		
		//右侧的搜索配置
		var baseCfg = {
			autoScroll : true,
			bbar : this.pageBar,
			items : [this.viewCfg]
		};
		
		if (this.searchAsToolBar===false) {
			baseCfg.items.unshift(this.searchCfg);
			baseCfg.layout = 'anchor';
		} else {
			baseCfg.tbar = {
				items : [this.searchCfg]
			};
		}
		
		this.ctCls = this.ctCls ? this.ctCls+' rscls-search-view-ct' : 'rscls-search-view-ct';
		Ext.apply(this, baseCfg);
		
		Hxcy.SearchView.superclass.initComponent.call(this);
		
		if (this.searchAsToolBar===false) {
		} else {
			this.listView = this.items.itemAt(0);
		}
		
	}
});
Ext.reg('searchview', Hxcy.SearchView);

Hxcy.ItemSelector = function(config) {
	Hxcy.ItemSelector.superclass.constructor.call(this, config);
};

Ext.extend(Hxcy.ItemSelector, Ext.Container, {
	initComponent : function(){
		//在这里组织临时变量, 将来如果增强或修复BUG有可能起用
		//配置组件的尺寸(包括provider与receiver)
		var pvdHeight = this.pvdHeight||350;//左边组件高度默认为350,此时窗体假设为450*450
		var pvdWidth = this.pvdWidth;//没有默认值,默认使用百分比进行活动控制;
		var rcvHeight = this.rcvHeight || pvdHeight;
		var rcvWidth = this.rcvWidth || pvdWidth;
		
		//配置组件的数据源(包括provider与receiver)
		var pvdStore = this.pvdStore;
		var rcvStore = this.rcvStore;
		//这里决定是使用外部配置,还是内置配置
		var provider = this.provider;
		var receiver = this.receiver;
		delete this.provider;
		delete this.receiver;
		if (!provider && !pvdStore) {
			Hxcy.Util.error('你必须指定一个完整的外部provider或提供一个内置配置的pvdStore');
			return;
		}
		//如果配置pvdStore说明使用内置的provider
		if (!provider) {//内置情况下你需要配置关于视图一些选项
			var pvdLimit = this.pvdLimit;
			var pvdSearchLabel = this.pvdSearchLabel;
			var pvdSearchName = this.pvdSearchName;
			var pvdColumns = this.pvdColumns||[{header:pvdSearchLabel, dataIndex:pvdSearchName}];
			var pvdSearchCfg = this.pvdSearchCfg || {};
			var pvdViewCfg = this.pvdViewCfg || {};
			if (!pvdSearchLabel||!pvdSearchName) {
				Hxcy.Util.error('你必须指定一个在provider中使用查询名称pvdSearchName与标题pvdSearchLabel');
				return;
			}
			Ext.applyIf(pvdSearchCfg, {
				anchor : '99%',
				xtype : 'singlesearch',
				width : this.searchWidth||180,
				limit : pvdLimit,
				minCharsTipText:'至少需要输入{0}个字符,才可以进行查询',
				menuStyle : 'radio',
				minChars : 1,
				menuItems : [{text:pvdSearchLabel,name:pvdSearchName}]
			});
			
			Ext.applyIf(pvdViewCfg, {
				xtype : 'listview',
				disableHeaders : true,
				hideHeaders : true,
				singleSelect: false,
				multiSelect: true,
				emptyText: this.emptyText||'没有符合要求的记录',
				columns: pvdColumns
			});
			
			provider = {
				xtype : 'searchview',
				cls : 'rscls-singlesearch-compact',//紧缩工具栏高度
				//bodyStyle : 'padding:5px;',
				searchStore : pvdStore,
				searchLabel : pvdSearchLabel,
				searchName : pvdSearchName,
				limit : pvdLimit,
				columns : pvdColumns,
				searchCfg : pvdSearchCfg,
				viewCfg : pvdViewCfg,
				width : pvdWidth || 'auto',
				height : pvdHeight,
				inTable : true,
				rowspan : 2,
				tdAttr : {style:'width:50%;padding-left:5px;', align:'center'}
			}
		}
		
		//说明并没有配置一个外置的receiver,因此需要在内部组件一个,默认使用listview组件
		if (!receiver) {
			rcvStore = rcvStore || new Ext.data.Store({reader:pvdStore.reader});//默认使用提供者了数据类型构造
			var rcvSearchLabel = this.rcvSearchLabel||pvdSearchLabel;
			var rcvSearchName = this.rcvSearchName||pvdSearchName;
			var rcvColumns = this.rcvColumns||[{header:rcvSearchLabel, dataIndex:rcvSearchName}];;
			var rcvViewCfg = this.rcvViewCfg || {};
			if (!rcvSearchLabel||!rcvSearchName) {
				Hxcy.Util.error('你必须指定一个在receiver中使用查询名称rcvSearchName与标题rcvSearchLabel');
				return;
			}
			receiver = {
				xtype : 'listview',
				cls : 'rscls-item-selector-receiver',
				store: rcvStore,
				disableHeaders : true,
				hideHeaders : true,
				singleSelect: false,
				multiSelect: true,
				emptyText: this.emptyText||'当前没有被选中的记录',
				columns: rcvColumns,
				
				inTable : true,
				autoScroll : true,
				rowspan : 2,
				height : rcvHeight,
				width : rcvWidth,
				tdAttr : {style:'width:50%;padding-right:5px;'}
			};
			
			var rcvBaseViewCfg = {
				xtype : 'listview',
				//reserveScrollOffset : true,
				//scrollOffset : 30,
				store: rcvStore,
				disableHeaders : true,
				hideHeaders : true,
				width : rcvWidth ? rcvWidth-20 : rcvWidth,
				singleSelect: false,
				multiSelect: true,
				emptyText: this.emptyText||'当前没有被选中的记录',
				columns: rcvColumns
			}
			Ext.apply(rcvBaseViewCfg, rcvViewCfg);//外部覆盖默认
			receiver = {
				inTable : true,
				autoScroll : true,
				//layout:'fit',
				rowspan : 2,
				//bodyStyle : 'padding:5px;',
				height : rcvHeight,
				width : rcvWidth,
				tdAttr : {style:'width:50%;padding-right:5px;', align:'center'},
				items : [rcvBaseViewCfg]
			};
		}
		
		//这个方法在超类方法之前执行很重要
		Ext.apply(this, {
			layout : 'tableform',
			ctCls : this.ctCls ? this.ctCls+' rscls-item-selector-ct' : 'rscls-item-selector-ct',
			layoutConfig: {
				 tableAttrs : {align:'center', width:'100%',height:'100%'},
				 columns: 3
			},
			items : [provider, {
				inTable : true,
				iconCls : 'rscls-move-right',
				tdAttr : {style:'vertical-align:bottom;padding:10px 5px 30px 5px;', width:'50px'},
				scale: 'medium',
				//text : '添  加',
				xtype : 'button',
				handler : this.onRight.createDelegate(this)
			}, receiver, {
				inTable : true,
				iconCls : 'rscls-move-left',
				tdAttr : {style:'vertical-align:top;padding:10px 5px 30px 5px;', width:'50px'},
				scale: 'medium',
				//text : '删  除',
				xtype : 'button',
				handler : this.onLeft.createDelegate(this)
			}]
	
		});
		Hxcy.ItemSelector.superclass.initComponent.call(this);
	},
	
	onRender : function(ct, position){
		Hxcy.ItemSelector.superclass.onRender.call(this, ct, position);
		this.provider = this.items.itemAt(0);
		this.pvdViewList = this.provider.listView;
		this.receiver = this.items.itemAt(2);
		this.rcvViewList = this.receiver.items.itemAt(0);
		
		this.pvdStore = this.pvdViewList.store;
		this.rcvStore = this.rcvViewList.store;
	},
	
	onRight : function(){
		var rds = this.pvdViewList.getSelectedRecords();
		for (var i = 0; i < rds.length; i++) {
			if (this.rcvStore.indexOfId(rds[i].id)>=0) {
				Hxcy.Util.msg('被选择的记录已经添加');
				return;
			}
		}
		this.rcvStore.add(rds);
		this.rcvViewList.refresh();
	},
	
	onLeft : function(){
		var rds = this.rcvViewList.getSelectedRecords();
		for (var i = 0; i < rds.length; i++) {
			this.rcvStore.remove(rds[i]);
		}
	},
	
	loadPvdStore : function(){
		this.provider.pageBar.moveFirst();
	},
	
	loadRcvStore : function(config){
		this.rcvStore.load(config);
	},
	
	clearRcvStore : function(){
		this.rcvStore.removeAll();
	},
	
	getResults : function(){
		return this.rcvStore.getRange();
	}
});
Ext.reg('itemselector', Hxcy.ItemSelector);

Hxcy.SearchForm = Ext.extend(Ext.form.FormPanel, {
	initComponent :function(){
		Hxcy.SearchForm.superclass.initComponent.call(this);
		
	},
	submit : function(options){
		options = options || {};
		options.params = options.params||{};
		var formParams = this.getForm().getValues();
		if(this.bind===true){
			Ext.apply(this.store.baseParams, formParams);
		} else {
			Ext.applyIf(options.params, formParams);
		}
		Hxcy.Util.cfg(options, this.store.lastOptions);
		if (this.clearPage!==false) {
			options.params['page.start'] = 0;
		}
		//写了转换器之后,这里就没必要
		/*
		for(var f in formParams){
			var v = this.getForm().findField(f).getValue();
			if(Ext.isEmpty(v)){//如果不空值则不向后台传值,因为由于转换器的原因传空值有可能变成false
				delete options.params[f];
			}
		}
		alert(Hxcy.Util.list(options.params));
		*/
		this.store.reload(options);
	},
	reset : function(options){
		options = options || {};
		options.params = options.params||{};
		var formParams = this.getForm().getValues();
		if(this.bind===true){
			var formParams = this.getForm().getValues();
			for(var name in formParams){
				delete this.store.baseParams[name];
			}
		}
		Ext.applyIf(options.params, formParams);
		Hxcy.Util.cfg(options, this.store.lastOptions);
		for(var f in formParams){
			var sfield=this.getForm().findField(f);
			var v = sfield==null?null:sfield.getValue();
			if(Ext.isEmpty(v)){//如果不空值则不向后台传值,因为由于转换器的原因传空值有可能变成false
				delete options.params[f];
			}
		}
		this.store.reload(options);
		this.getForm().reset();
	}
});
Ext.reg('searchform', Hxcy.SearchForm);

Ext.ns('Ext.ux.layout');
Ext.ux.layout.CenterLayout = Ext.extend(Ext.layout.FitLayout, {
	// private
	setItemSize : function(item, size) {
		this.container.addClass('ux-layout-center');
		item.addClass('ux-layout-center-item');
		if (item && size.height > 0) {
			if (item.width) {
				size.width = item.width;
			}
			item.setSize(size);
		}
	}
});
Ext.Container.LAYOUTS['ux.center'] = Ext.ux.layout.CenterLayout;

Hxcy.CheckCombo = Ext.extend(Ext.form.ComboBox, {

	checkField:'checked',
	
	checkedClass : 'rscls-item-checked',
	
	separator:',',

	initComponent:function() {
		if(!this.tpl) {
			this.tpl = new Ext.XTemplate(
				'<tpl for=".">',
				'<div class="x-combo-list-item">',
				'<span class="rscls-checkcombo-icon">&#160;</span>&#160;',
				'<span class="rscls-checkombo-item-text">{' + (this.displayField || 'text' )+ '}</span>',
				'</div>',
				'</tpl>'
			);
		}
		//调用超类的方法
		Hxcy.CheckCombo.superclass.initComponent.apply(this, arguments);
	},
	
	initEvents : function(){
		Hxcy.CheckCombo.superclass.constructor.superclass.initEvents.call(this);//屏蔽键盘响应
		this.queryDelay = Math.max(this.queryDelay || 10,
				this.mode == 'local' ? 10 : 250);
		this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
		if(this.typeAhead){
			this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
		}
		if(this.editable !== false && !this.enableKeyEvents){
			this.mon(this.el, 'keyup', this.onKeyUp, this);
		}
	},
	
	// private
	initList : function(){
		if(!this.list){
			var cls = 'x-combo-list';

			this.list = new Ext.Layer({
				parentEl: this.getListParent(),//这里将列表的父结点设置body,因为是层所以没有太大关系
				shadow: this.shadow,//阴影设置
				cls: [cls, this.listClass].join(' '),//列表的样式类
				constrain:false
			});

			//注意这里有一个wrap是超继承过来的TriggerField,其形式:<div><input.....><img ...></div>
			//因为在前面又插入了隐藏域所以变成了<div><input type=hidden....><input type=text....><img ...></div>
			var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
			this.list.setSize(lw, 0);//设置列表的宽度
			this.list.swallowEvent('mousewheel');
			this.assetHeight = 0;
			if(this.syncFont !== false){//同步字体
				this.list.setStyle('font-size', this.el.getStyle('font-size'));
			}
			if(this.title){//创建一个列表标题
				this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
				this.assetHeight += this.header.getHeight();//添加第一个内嵌高度
			}

			this.innerList = this.list.createChild({cls:cls+'-inner'});
			this.mon(this.innerList, 'mousemove', this.onViewMove, this);
			this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));//设置内嵌列表的宽度,有总宽度减去外列表的左右边界

			if(this.pageSize){//如果添加分页
				this.footer = this.list.createChild({cls:cls+'-ft'});
				this.pageTb = new Ext.PagingToolbar({
					store: this.store,
					pageSize: this.pageSize,
					renderTo:this.footer
				});
				this.assetHeight += this.footer.getHeight();//添加第二个内嵌高度
			}

			/**
			 * 初始化视图,这个视图是显示在内嵌列表中的
			* The {@link Ext.DataView DataView} used to display the ComboBox's options.
			* @type Ext.DataView
			*/
			this.view = new Ext.DataView({
				applyTo: this.innerList,//将这个视图渲染到内嵌列表
				tpl: this.tpl,
				simpleSelect : true,
				overClass : this.selectedClass,
				multiSelect: true,//因为是一个combo,一次只能选择一个,所以设置单选视图
				//将这里的checkedClass被选中的状态设置为view的selectedClass,而原始设置combo中设置seelctedClass设置成view的overClass
				selectedClass: this.checkedClass,
				itemSelector: this.itemSelector || '.' + cls + '-item',
				emptyText: this.listEmptyText
			});

			this.mon(this.view, 'click', this.onViewClick, this);//为视图绑定监听

			this.bindStore(this.store, true);//绑定store到视图

			if(this.resizable){//处理列表拖动,改变列表大小
				this.resizer = new Ext.Resizable(this.list,  {
				   pinned:true, handles:'se'
				});
				this.mon(this.resizer, 'resize', function(r, w, h){
					this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
					this.listWidth = w;
					this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
					this.restrictHeight();
				}, this);

				this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
			}
		}
	},
	
	// private 因为onLoad方法使用了默认选择第一条规则所以这里重写
	onLoad : function(){
		if(!this.hasFocus){
			return;
		}
		//加载完成后如果有数据才执行
		if(this.store.getCount() > 0){
			this.expand();
			this.restrictHeight();
			if(this.lastQuery == this.allQuery){
				if(this.editable){
					this.el.dom.select();
				}
				if(!this.selectByValue(this.value, true)){
					//this.select(0, true);//修改这里不选择第一条
				}
			}else{
				//this.selectNext();//这里不选择下一条
				if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
					this.taTask.delay(this.typeAheadDelay);
				}
			}
		}else{//如果没有则执行
			this.onEmptyResults();
		}
		//this.el.focus();
	},
	
	onSelect:function(recordArray, indexArray, index) {
		if(this.fireEvent('beforeselect', this, recordArray, indexArray) !== false){
			//这里值与超类的含义已经不同了
			this.setValue(recordArray);
			
			this.fireEvent('select', this, recordArray, indexArray);
		}
	},
	select : function(index, scrollIntoView){
		this.selectedIndex = index;
		//切换样式
		//Ext.fly(this.view.getNode(index)).toggleClass(this.checkedClass);
		this.view.select(index, true);//这个地方将视图记录选择时将原来被选择记录保持
		if(scrollIntoView !== false){
			var el = this.view.getNode(index);
			if(el){
				this.innerList.scrollChildIntoView(el, false);
			}
		}
	},
	//在下拉列表根据数据值选择记录,此方法必须在store已经加载并且下拉列表已经展开的情况,此方法将会在
	//store加载完成后调用以选择记录, 这个方法需要修改
	selectByValue : function(v, scrollIntoView){
		if(!Ext.isEmpty(v, true)){
			var r = this.findRecord(this.valueField || this.displayField, v);
			if(r){
				this.select(this.store.indexOf(r), scrollIntoView);
				return true;
			}
		}
		return false;
	},
	
	setValue:function(v) {
		if(!Ext.isArray(v)){//可能是第一次初始值
			//在这里检测列表是否已经渲染,如果是,则进行input值设置,从表单加载数据主要逻辑
			if(!this.list){
				this.initList();
			}
			//视图清理时,带上第二个参数为false,表示不跳过更新界面,这样可以去除selectedClass,
			this.view.clearSelections(false, false);
			if(this.hiddenField){
				this.hiddenField.value = v;
			}
			v = Ext.isEmpty(v)?'':v;
			v = Ext.isString(v)?v:v+'';
			this.value = v;
			var values = v.split(',');
			var texts = [];
			Ext.each(values, function(v){
				var index = this.store.indexOfId(v);
				var rd = this.store.getById(v);
				if(rd){//因为有可能出现数据异常,id在store找不到对应的记录
					this.select(index);
					texts.push(rd.get(this.displayField));
				}
			}, this);
			texts = Ext.isEmpty(texts)?this.valueNotFoundText:texts.join(',');
			
			Ext.form.ComboBox.superclass.setValue.call(this, texts);
			return this;
		}
		var recordArray = v;
		var v = this.extractValue(recordArray, this.valueField||this.displayField);
		var text = this.extractValue(recordArray, this.displayField);
		text = Ext.isEmpty(text)?this.valueNotFoundText : text;
		this.lastSelectionText = text;
		if(this.hiddenField){
			this.hiddenField.value = v;
		}
		Ext.form.ComboBox.superclass.setValue.call(this, text);
		this.value = v;
		return this;
	},
	
	extractValue : function(recordArray, fieldName){
		recordArray = recordArray || [];
		var result = [];
		Ext.each(recordArray, function(record){
			result.push(record.get(fieldName));
		});
		return result.join(',');
	},

	// private
	onViewClick : function(view, index, node, e){
		var indexArray = this.view.getSelectedIndexes();
		var recordArray = this.view.getSelectedRecords();
		this.onSelect(recordArray, indexArray, index);
		if(view !== false){
			this.el.focus();
		}
	},
	 // private 此方法调用了setValue所以重写
	beforeBlur : function(){
		var val = this.view.getSelectedRecords();//在这里更改
		if(this.forceSelection){
			if(val.length > 0 && val != this.emptyText){
			   this.el.dom.value = Ext.isDefined(this.lastSelectionText) ? this.lastSelectionText : '';
				this.applyEmptyText();
			}else{
				this.clearValue();
			}
		}else{
			var rec = this.findRecord(this.displayField, val);
			if(rec){
				val = rec.get(this.valueField || this.displayField);
			}
			//this.setValue(val);在这里更改,不做值的设置,因为这样会导致重置
		}
	}
});
Ext.reg('checkcombo', Hxcy.CheckCombo); 
 
//=====================================以下为未调整方法=============================================
Hxcy.MasterSlavePanel = function(config) {
	config.layout = 'border';
	config.sconfig = config.sconfig || {};
	var master = config.master;
	var slave = config.slave;
	if(!config.direction||config.direction=='ud'||config.direction=='up-down'){
		if (config.exchange===true) {
			master.region = 'south';
			slave.region = 'center';
			master.height = config.sconfig.size || 200;
		} else {
			master.region = 'center';
			slave.region = 'south';
			slave.height = config.sconfig.size || 200;
		}
	} else if(config.direction=='lr'||config.direction=='left-right'){
		if (config.exchange===true) {
			master.region = 'east';
			slave.region = 'center';
			master.width = config.sconfig.size || 600;
		} else {
			master.region = 'center';
			slave.region = 'east';
			slave.width = config.sconfig.size || 600;
		}
	} else {
		alert('指定的方向不正确');
	}
	
	if (config.exchange===true) {
		Hxcy.Util.applyIf(master, config.sconfig);
		Hxcy.Util.applyIf(slave, config.mconfig);
	} else {
		Hxcy.Util.applyIf(master, config.mconfig);
		Hxcy.Util.applyIf(slave, config.sconfig);
	}
	
	config.items = [master, slave];
	Hxcy.MasterSlavePanel.superclass.constructor.call(this, config);
};

Ext.extend(Hxcy.MasterSlavePanel, Ext.Panel, {
	initEvents : function(){
		Hxcy.MasterSlavePanel.superclass.initEvents.call(this);
		var master = this.master = this.items.itemAt(0);
		var slave = this.slave = this.items.itemAt(1);
		var cascade = this.cascade;
		//让从表可以感知主表的事件
		master.fireEvent = function(){
			var ename = arguments[0];
			var args = ['master'+ename].concat(Ext.toArray(arguments).slice(1));
			Ext.Panel.prototype.fireEvent.apply(master, arguments);
			if (cascade===true) {
				slave.cascade(function(){
					Ext.Panel.prototype.fireEvent.apply(this, args);
				}, null, null);
			} else {
				Ext.Panel.prototype.fireEvent.apply(slave, args);
				if(slave.items){
					slave.items.each(function(item){
						Ext.Panel.prototype.fireEvent.apply(item, args);
					});
				}
			}
		};
		
		//这里添加条件,因为有可能出现master不为表格的情况
		if (master.selModel) {
			master.selModel.fireEvent = function(){
				var ename = arguments[0];
				var args = ['master'+ename].concat(Ext.toArray(arguments).slice(1));
				Ext.grid.AbstractSelectionModel.prototype.fireEvent.apply(master.selModel, arguments);
				if (cascade===true) {
					slave.cascade(function(){
						Ext.grid.AbstractSelectionModel.prototype.fireEvent.apply(this, args);
					}, null, null);
				} else {
					Ext.Panel.prototype.fireEvent.apply(slave, args);
					if(slave.items){
						slave.items.each(function(item){
							Ext.grid.AbstractSelectionModel.prototype.fireEvent.apply(item, args);
						});
					}
				}
			};
		}
		
		//这里添加条件,因为有可能出现master不为表格的情况
		if (master.store) {
			master.store.fireEvent = function(){
				var ename = arguments[0];
				var args = ['master'+ename].concat(Ext.toArray(arguments).slice(1));
				Ext.data.Store.prototype.fireEvent.apply(master.store, arguments);
				if (cascade===true) {
					slave.cascade(function(){
						Ext.data.Store.prototype.fireEvent.apply(this, args);
					}, null, null);
				} else {
					Ext.Panel.prototype.fireEvent.apply(slave, args);
					if(slave.items){
						slave.items.each(function(item){
							Ext.data.Store.prototype.fireEvent.apply(item, args);
						});
					}
				}
			};
		}
		
		if(this.mask!==false){
			if (master.selModel) {
				master.selModel.addListener('rowselect', this.onSlaveUnmask, this);
				master.selModel.addListener('rowdeselect', this.onSlaveMask, this);
			}
			if (master.store) {
				master.store.addListener('load', this.onSlaveMask, this);
			}
		}
		
		//是否监听主表的选择与取消选择事件
		if (this.listenerMaster!==false) {
			if (master.selModel) {
				master.selModel.addListener('rowselect', this.onMasterSelect, this);
				master.selModel.addListener('rowdeselect', this.onMasterDeselect, this);
			}
			if (master.store) {
				master.store.addListener('load', this.onMasterDeselect, this);
			}
		}
		
	},
	onSlaveUnmask : function(masterSM, rowIndex, rd){
		var fn = function(masterSM, rowIndex, rd){
			var slave = this.slave;
			if (typeof slave.maskCallback=='function'&&slave.maskCallback(this.master)) {
				slave.getEl().mask();//需要锁定从表
			} else {
				slave.getEl().unmask();
			}
		}
		if(!this.loadTask){
			this.maskTask = new Ext.util.DelayedTask(fn, this);
		}
		this.maskTask.delay(10, null, null, [masterSM, rowIndex, rd]);
	},
	onSlaveMask : function(masterSM, rowIndex, rd){
		var slave = this.slave;
		if (typeof slave.maskCallback=='function'&&(!slave.maskCallback(this.master))) {
			slave.getEl().unmask();//需要锁定从表
		} else {
			slave.getEl().mask();
		}
	},
	getLoadTask : function(){
		if(!this.loadTask){
			this.loadTask = new Ext.util.DelayedTask(Ext.emptyFn, this);
		}
		return this.loadTask;
	},
	onMasterSelect : function(masterSM, rowIndex, rd){
		var fn = function(masterSM, rowIndex, rd){
			var slave = this.slave;
			var baseParams = {};
			for(var p in slave.masterParams){
				baseParams[p]=rd.get(slave.masterParams[p]);
			}
			Ext.apply(slave.store.baseParams, baseParams||{});
			slave.bottomToolbar.moveFirst();
		}
		
		this.getLoadTask().delay(10, fn, this, [masterSM, rowIndex, rd]);
	},
	onMasterDeselect : function(masterSM, rowIndex, rd){
		var slave = this.slave;
		for(var p in slave.masterParams){
			delete slave.store.baseParams[p];
		}
		if (slave.deselectStrategy=='reload') {
			var fn = function(){
				slave.bottomToolbar.moveFirst();
			}
			this.getLoadTask().delay(10, fn, this, [masterSM, rowIndex, rd]);
		} else if(!slave.deselectStrategy||slave.deselectStrategy=='clear'){
			slave.store.removeAll();
			slave.store.totalLength=0;
			var bar = slave.getTopToolbar();
			if (bar.pageSize) {
				bar.onLoad(slave.store, null, {});
			}
			bar = slave.getBottomToolbar();
			if (bar.pageSize) {
				bar.onLoad(slave.store, null, {});
			}
		}
	}
});

Ext.reg('mspanel', Hxcy.MasterSlavePanel);



Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
	initComponent : function() {
		Ext.app.SearchField.superclass.initComponent.call(this);
		this.on('specialkey', function(f, e) {
					if (e.getKey() == e.ENTER) {
						this.onTrigger2Click();
					}
				}, this);
		this.otherFields = this.otherFields || [];
		if (!Ext.isArray(this.otherFields)) {
			this.otherFields = [this.otherFields];
		}
		this.selfField ? this.otherFields.push(this.id) : "";
	},

	validationEvent : false,
	validateOnBlur : false,
	trigger1Class : 'x-form-clear-trigger',
	trigger2Class : 'x-form-search-trigger',
	hideTrigger1 : true,
	width : 180,
	selfField : true,
	paramNames : {
		start : 'page.start'
	},

	prepareData : function() {
		this.store.baseParams = this.store.baseParams || {};
		Ext.each(this.otherFields, function(item) {
					var field = Ext.getCmp(item);
					//这里不要使用field.getValue或field.getRawValue,如果使用field.getValue,则获取的值是一个有类型值可能与设定的格式不符合,例如日期;
					//如果是getRawValue可能获取并不是我们需要的值,例如下拉列表获取的是看得见的标签的值；但这里又出现一个问题像文本域非触发形的字段域，此值却为空
					this.store.baseParams[field.getName()] = field.value||field.getRawValue();
				}, this);

	},

	resetData : function() {
		this.store.baseParams = this.store.baseParams || {};
		Ext.each(this.otherFields, function(item) {
					var field = Ext.getCmp(item);
					field.reset();
					if (field.resetClear!==false) {//由字段配置来决定是否清除
						delete this.store.baseParams[field.getName()];
						delete this.store.lastOptions.params[field.getName()];
					} else {
						this.store.baseParams[field.getName()] = field.value||field.getRawValue();
					}
				}, this);
	},

	hasSearch : function() {
		return Ext.each(this.otherFields, function(item) {
					var field = Ext.getCmp(item);
					if (field.getRawValue()) {
						return false;
					};
				}, this) == undefined ? false : true;
	},

	onTrigger1Click : function() {
		if (this.hasSearch()) {
			this.el.dom.value = '';
			var o = {};
			if (this.clearPage!==false) {
				this.store.lastOptions.params[this.paramNames.start] = 0;
			}
			this.resetData();
			this.store.reload();
			this.triggers[0].hide();
		}
	},

	onTrigger2Click : function() {
		if (!this.hasSearch()) {
			this.onTrigger1Click();
			return;
		}
		var o = {};
		//以下这一行以前是注释的
		this.store.lastOptions = this.store.lastOptions || {params : {}};
		this.store.lastOptions.params = this.store.lastOptions.params || {};
		if (this.clearPage!==false) {
			this.store.lastOptions.params[this.paramNames.start] = 0;
		}
		this.prepareData();
		this.store.reload();
		this.triggers[0].show();
	}
});

Ext.reg('searchfield', Ext.app.SearchField);

Ext.ns('Ext.ux.layout');
Ext.ux.layout.CenterLayout = Ext.extend(Ext.layout.FitLayout, {
	// private
	setItemSize : function(item, size) {
		this.container.addClass('ux-layout-center');
		item.addClass('ux-layout-center-item');
		if (item && size.height > 0) {
			if (item.width) {
				size.width = item.width;
			}
			item.setSize(size);
		}
	}
});
Ext.Container.LAYOUTS['ux.center'] = Ext.ux.layout.CenterLayout;

Ext.ux.layout.RowLayout = Ext.extend(Ext.layout.ContainerLayout, {
	// private
	monitorResize : true,

	// private
	isValidParent : function(c, target) {
		return c.getEl().dom.parentNode == this.innerCt.dom;
	},

	// private
	onLayout : function(ct, target) {
		var rs = ct.items.items, len = rs.length, r, i;

		if (!this.innerCt) {
			target.addClass('ux-row-layout-ct');
			this.innerCt = target.createChild({
				cls : 'x-row-inner'
			});
		}
		this.renderAll(ct, this.innerCt);

		var size = target.getViewSize();

		if (size.width < 1 && size.height < 1) { // display none?
			return;
		}

		var h = size.height - target.getPadding('tb'), ph = h;

		this.innerCt.setSize({
			height : h
		});

		// some rows can be percentages while others are fixed
		// so we need to make 2 passes

		for (i = 0; i < len; i++) {
			r = rs[i];
			if (!r.rowHeight) {
				ph -= (r.getSize().height + r.getEl().getMargins('tb'));
			}
		}

		ph = ph < 0 ? 0 : ph;

		for (i = 0; i < len; i++) {
			r = rs[i];
			if (r.rowHeight) {
				r.setSize({
					height : Math.floor(r.rowHeight * ph) - r.getEl().getMargins('tb')
				});
			}
		}
	}

		/**
		 * @property activeItem
		 * @hide
		 */
	});
Ext.Container.LAYOUTS['ux.row'] = Ext.ux.layout.RowLayout;


/**
 * @class Ext.ux.TreeCheckNodeUI
 * @extends Ext.tree.TreeNodeUI
 * 
 * 对 Ext.tree.TreeNodeUI 进行checkbox功能的扩展,后台返回的结点信息不用非要包含checked属性
 * 
 * 扩展的功能点有：
 * 一、支持只对树的叶子进行选择
 *	只有当返回的树结点属性leaf = true 时，结点才有checkbox可选
 * 	  使用时，只需在声明树时，加上属性 onlyLeafCheckable: true 既可，默认是false
 * 
 * 二、支持对树的单选
 *	只允许选择一个结点
 * 	  使用时，只需在声明树时，加上属性 checkModel: "single" 既可
 * 
 * 二、支持对树的级联多选 
 *	主要由两个选项来控制:bubbleCheck与cascadeCheck这两个选项都可取如下四个值:all, check, uncheck, none
 * 
 * 使用方法：在loader里加上 baseAttrs:{uiProvider:Ext.ux.TreeCheckNodeUI} 既可.
 * 例如：
 *   var tree = new Ext.tree.TreePanel({
 *		el:'tree-ct',
 *		width:568,
 *		height:300,
 *		checkModel: 'cascade',   //对树的级联多选
 *		onlyLeafCheckable: false,//对树所有结点都可选
 *		animate: false,
 *		CPTVisible: false,
 *		autoScroll:true,
 *		loader: new Ext.tree.DWRTreeLoader({
 *			dwrCall:Tmplt.getTmpltTree,
 *			baseAttrs: { uiProvider: Ext.ux.TreeCheckNodeUI } //添加 uiProvider 属性
 *		}),
 *		CPT: new Ext.tree.AsyncTreeNode({ id:'0' })
 *	});
 *	tree.on("check",function(node,checked){alert(node.text+" = "+checked)}); //注册"check"事件
 *	tree.render();
 * 
 */

Ext.ux.TreeCheckNodeUI = function() {
	//多选: 'multiple'(默认)
	//单选: 'single'
	//级联多选: 'cascade'(同时选父和子);'parentCascade'(选父);'childCascade'(选子)
	this.checkModel = 'multiple';
	
	//向下关联选择的模式,可以取的值:none, checked, unchecked, all;
	this.bubbleCheck = 'checked';
	
	//向下关联选择的模式,可以取的值:none, checked, unchecked, all;
	this.cascadeCheck = 'unchecked';
	
	//表示是否只有叶子节才有checkbox可以选择
	this.onlyLeafCheckable = false;
	
	//表示是否启用单选模式
	this.singleModel = false;
	
	Ext.ux.TreeCheckNodeUI.superclass.constructor.apply(this, arguments);
};

Ext.extend(Ext.ux.TreeCheckNodeUI, Ext.tree.TreeNodeUI, {

	checkedCls: 'x-tree-node-checked',//checkbox选中时的类
	disableCls: 'x-tree-node-disabled',//checkbox禁用时的类
	focusCls: 'x-tree-checkbox-focus',//checkbox获取焦点时的类
	overCls: 'x-tree-checkbox-over',//checkbox悬停时的类
	mouseDownCls: 'x-tree-checkbox-down',//鼠标按下的类
	
	renderElements : function(n, a, targetNode, bulkRender){
		var tree = n.getOwnerTree();
		this.bubbleCheck = tree.bubbleCheck || this.bubbleCheck;
		this.cascadeCheck = tree.cascadeCheck || this.cascadeCheck;
		this.onlyLeafCheckable = tree.onlyLeafCheckable || this.onlyLeafCheckable;
		this.singleModel = tree.singleModel || this.singleModel;
		
		// add some indent caching, this helps performance when rendering a large tree
		this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';

		//var cb = typeof a.checked == 'boolean';
		var cb = (!this.onlyLeafCheckable || a.leaf);
		var href = a.href ? a.href : Ext.isGecko ? "" : "#";
		var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
			'<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
			'<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
			'<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
			cb ? '<img src="'+this.emptyIcon+'" class="x-tree-checkbox'+(true === a.checked ? ' '+this.checkedCls :'')+'" />' : '',
			'<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
			 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
			'<ul class="x-tree-node-ct" style="display:none;"></ul>',
			"</li>"].join('');

		var nel;
		if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
			this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
		}else{
			this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
		}
		
		this.elNode = this.wrap.childNodes[0];
		this.ctNode = this.wrap.childNodes[1];
		var cs = this.elNode.childNodes;
		this.indentNode = cs[0];
		this.ecNode = cs[1];
		this.iconNode = cs[2];
		var index = 3;
		if(cb){
			this.checkbox = cs[3];//让包装就是checkbox
			index++;
		}
		this.anchor = cs[index];
		this.textNode = cs[index].firstChild;
	},
	
	//重写此方法是因为改写后判定isChicked的逻辑发生了变化
	isChecked:function() {
		return this.node.attributes.checked === true;
	},
	
	onCheckChange:function() {
		//var checked = this.isChecked();//这是没有切换前的状态
		/*******************此处先添加状态切换*********************/
		var checked = this.toggleCheck();
		/************************************************/
		var tree = this.node.getOwnerTree();
		if(this.singleModel==true){
			var checkedNodes = tree.getChecked();
			for(var i=0;i<checkedNodes.length;i++){
				var node = checkedNodes[i];
				if(node.id != this.node.id){
					node.ui.setChecked(false);
				}
			}
		} else if(!this.onlyLeafCheckable){//级联与onlyLeafCheckable是互斥的
			var bubble = this.bubbleCheck;
			var cascade = this.cascadeCheck;
	
			if('all' === cascade || (checked && 'checked' === cascade) || (!checked && 'unchecked' === cascade)) {
				this.updateChildren(checked);
			}
			if('all' === bubble || (checked && 'checked' === bubble) || (!checked && 'unchecked' === bubble)) {
				this.updateParent(checked);
			}
		}

		//tree.updateHidden();
		this.fireEvent('checkchange', this.node, checked);
	},
	
	setChecked:function(checked) {
		checked = true === checked ? checked : false;
		var cb = this.checkbox ? Ext.fly(this.checkbox) : false;
		if(cb) {
			true === checked ? cb.addClass('x-tree-node-checked') : cb.removeClass('x-tree-node-checked');
		}
		this.node.attributes.checked = checked;//表示当前结点的check状态
		this.node.checked = true;//表示当前结点已经被点击过至少一次,
		
		//下面这行代码是处整个多重递归的核心环节,由于多重递归非常容易导致栈溢出,这里将这个多重递归阻断,并取而代之的是迭代,将它们放在
		//updateParent与updateChildren两个方法中
		//this.onCheckChange();
		return checked;
	},
	
	toggleCheck:function() {
		var checked = !this.isChecked();
		this.setChecked(checked);
		return checked;
	},
	//此方法与setChecked,onCheckChange,updateChildren形成了递归
	updateParent:function(checked) {
		var p = this.node.parentNode;
		var ui = p ? p.getUI() : false;
		
		if(ui && ui.setChecked) {
			ui.setChecked(checked);
		}
	}, 
	//将上面的方法改用迭代
	updateParent:function(checked) {
		var p = this.node.parentNode;
		var pp = p;
		while(!(pp.isCPT)){
			p = pp;
			pp = p.parentNode;
			if(!(checked ^ p.ui.isChecked()))continue;
			//如果当前结点有被选中的子结点,虽然当前结点要被设置未选中状态,但是因为还有子结点被选择，所以不改变状态
			if(!checked && this.childHasChecked(p))continue;
			p.ui.setChecked(checked);
			this.fireEvent('checkchange', p, checked);
		}
	},
	
	// private 当前结点是否有被选中的子结点//父类中没有此方法
	childHasChecked : function(node){
		var childNodes = node.childNodes;
		if(childNodes || childNodes.length>0){
			for(var i=0;i<childNodes.length;i++){
				if(childNodes[i].ui.isChecked())
					return true;
			}
		}
		return false;
	},
	
	//此方法与setChecked,onCheckChange,updateParent形成了递归
	updateChildren:function(checked) {
		this.node.eachChild(function(n) {
			var ui = n.getUI();
			if(ui && ui.setChecked) {
				ui.setChecked(checked);
			}
		});
	},
	//将上面的方法改为迭代实现
	updateChildren:function(checked) {
		var f = function(){
			if(this.ui.isChecked()!=checked){
				this.ui.setChecked(checked);
				this.fireEvent('checkchange', this, checked);
			}
		}
		this.node.cascade(f);
	},
	
	//主要是为了渲染所有的子结点//此类在父类方法中是没有的
	expandAllXXX : function(node){
		node = node || this.node;
		if( !this.node.expanded && !this.node.childrenRendered ) {
			this.node.expand(false,false);
			this.node.collapse(false,false);
		}
		if(!this.node.attributes.leaf) {
			var cs = this.node.childNodes;
			var csui;
			for(var i = 0; i < cs.length; i++) {
				csui = cs[i].getUI();
				csui.expandAll();
			}
		}
	},
	
	//此类在父类方法是没有
	resetChecked : function(node){
		node = node || this.node;
		var f = function(){
			this.ui.setChecked(false);
		}
		node.cascade(f);
	},
	
	//******************以下是为了完成事件模型的委托任务****************************
	onCheckboxClick:function() {
		if(!this.disabled) {
			//此处以前的代码是this.toggleCheck();我觉得这样不是很好,在原事件模型TreeEventMode中onCheckboxClick,调用是UI的onCheckChange
			//而新事件模型中调用的是UI的onCheckboxClick方法,也就是当前的方法,我觉得仍然应该在此方法中委托onCheckChange方法,而不应该是委托toggleCheck
			//方法
			this.onCheckChange();
		}
	},
	onCheckboxOver:function() {
		this.addClass(this.overCls);
	},
	onCheckboxOut:function() {
		this.removeClass(this.overCls);
	},
	onCheckboxDown:function() {
		this.addClass(this.mouseDownCls);
	},
	onCheckboxUp:function() {
		this.removeClass(this.mouseDownCls);
	}
});

//与上面的选择树配套的,树事件模型扩展

Ext.ux.CheckTreeEventModel = Ext.extend(Ext.tree.TreeEventModel, {
	 initEvents:function(){
		var el = this.tree.getTreeEl();
		el.on('click', this.delegateClick, this);
		if(this.tree.trackMouseOver !== false){
			this.tree.innerCt.on('mouseover', this.delegateOver, this);
			this.tree.innerCt.on('mouseout', this.delegateOut, this);
		}
		el.on('mousedown', this.delegateDown, this);
		el.on('mouseup', this.delegateUp, this);
		el.on('dblclick', this.delegateDblClick, this);
		el.on('contextmenu', this.delegateContextMenu, this);
	},
	delegateOut:function(e, t){
		if(!this.beforeEvent(e)){
			return;
		}
		if(e.getTarget('.x-tree-ec-icon', 1)){
			var n = this.getNode(e);
			this.onIconOut(e, n);
			if(n == this.lastEcOver){
				delete this.lastEcOver;
			}
		}
		else if(e.getTarget('.x-tree-checkbox', 1)){
			var n = this.getNode(e);
			this.onCheckboxOut(e, n);
			if(n == this.lastCbOver){
				delete this.lastCbOver;
			}
		}
		if((t = this.getNodeTarget(e)) && !e.within(t, true)){
			this.onNodeOut(e, this.getNode(e));
		}
	},
	delegateOver:function(e, t){
		if(!this.beforeEvent(e)){
			return;
		}
		if(this.lastEcOver){
			this.onIconOut(e, this.lastEcOver);
			delete this.lastEcOver;
		}
		if(this.lastCbOver){
			this.onCheckboxOut(e, this.lastCbOver);
			delete this.lastCbOver;
		}
		if(e.getTarget('.x-tree-ec-icon', 1)){
			this.lastEcOver = this.getNode(e);
			this.onIconOver(e, this.lastEcOver);
		}
		else if(e.getTarget('.x-tree-checkbox', 1)){
			this.lastCbOver = this.getNode(e);
			this.onCheckboxOver(e, this.lastCbOver);
		}
		if(t = this.getNodeTarget(e)){
			this.onNodeOver(e, this.getNode(e));
		}
	},
	delegateDown:function(e, t){
		if(!this.beforeEvent(e)){
			return;
		}
		if(e.getTarget('.x-tree-checkbox', 1)){
			this.onCheckboxDown(e, this.getNode(e));
		}
	},
	delegateUp:function(e, t){
		if(!this.beforeEvent(e)){
			return;
		}
		if(e.getTarget('.x-tree-checkbox', 1)){
			this.onCheckboxUp(e, this.getNode(e));
		}
	},
	delegateClick:function(e, t){
		if(!this.beforeEvent(e)){
			return;
		}
		if(e.getTarget('.x-tree-checkbox', 1)){
			this.onCheckboxClick(e, this.getNode(e));
		}
		else if(e.getTarget('.x-tree-ec-icon', 1)){
			this.onIconClick(e, this.getNode(e));
		}
		else if(this.getNodeTarget(e)){
			this.onNodeClick(e, this.getNode(e));
		}
	},
	onCheckboxClick:function(e, node){
		node.ui.onCheckboxClick();
	},
	onCheckboxOver:function(e, node){
		node.ui.onCheckboxOver();
	},
	onCheckboxOut:function(e, node){
		node.ui.onCheckboxOut();
	},
	onCheckboxDown:function(e, node){
		node.ui.onCheckboxDown();
	},
	onCheckboxUp:function(e, node){
		node.ui.onCheckboxUp();
	}
});

Ext.ux.CheckTreePanel = Ext.extend(Ext.tree.TreePanel, {
	initComponent:function() {
		this.eventModel = new Ext.ux.CheckTreeEventModel(this);

		Ext.ux.CheckTreePanel.superclass.initComponent.apply(this, arguments);

		// pass this.baseAttrs and uiProvider down the line
		var baseAttrs = Ext.apply({uiProvider:Ext.ux.TreeCheckNodeUI}, this.baseAttrs);
		Ext.applyIf(this.loader, {baseAttrs:baseAttrs, preloadChildren:false});

		// make sure that nodes are deeply preloaded
		if(true === this.loader.preloadChildren) {
			this.loader.on('load', function(loader, node) {
				node.cascade(function(n) {
					loader.doPreload(n);
					n.loaded = true;
				});
			});
		}
		if(true === this.filter) {
			var Filter = Ext.ux.TreeFilterX ? Ext.ux.TreeFilterX : Ext.tree.TreeFilter;
			this.filter = new Filter(this, {autoClear:true});
		}

	}
});

Ext.reg('checktreepanel', Ext.ux.CheckTreePanel);

/*comboboxtree  sxl 20100401*/
 
Ext.ux.ComboBoxTree = function(){
	this.treeId = Ext.id()+'-tree';
	this.maxHeight = arguments[0].maxHeight || arguments[0].height || this.maxHeight;
	this.tpl = new Ext.Template('<tpl for="."><div style="height:'+this.maxHeight+'px"><div id="'+this.treeId+'"></div></div></tpl>');
	this.store = new Ext.data.SimpleStore({fields:[],data:[[]]});
	this.selectedClass = '';
	this.mode = 'local';
	this.triggerAction = 'all';
	this.onSelect = Ext.emptyFn;
	this.editable = false;
	
	//all:所有结点都可选中
	//exceptCPT：除根结点，其它结点都可选
	//folder:只有目录（非叶子和非根结点）可选
	//leaf：只有叶子结点可选
	this.selectNodeModel = arguments[0].selectNodeModel || 'exceptCPT';
	
	Ext.ux.ComboBoxTree.superclass.constructor.apply(this, arguments);
}

Ext.extend(Ext.ux.ComboBoxTree,Ext.form.ComboBox, {
	
	expand : function(){
		Ext.ux.ComboBoxTree.superclass.expand.call(this);
		if(!this.tree.rendered){
			this.tree.height = this.maxHeight;
			this.tree.border=false;
			this.tree.autoScroll=true;
			if(this.tree.xtype){
				this.tree = Ext.ComponentMgr.create(this.tree, this.tree.xtype);
			}
			this.tree.render(this.treeId);
			var combox = this;
			this.tree.on('click',function(node){
				var isCPT = (node == combox.tree.getCPTNode());
				var selModel = combox.selectNodeModel;
				var isLeaf = node.isLeaf();
				if(isCPT && selModel != 'all'){
					return;
				}else if(selModel=='folder' && isLeaf){
					return;
				}else if(selModel=='leaf' && !isLeaf){
					return;
				}
				combox.setValueNode(node); 
				combox.collapse();
			});
			var CPT = this.tree.getCPTNode();
			if(!CPT.isLoaded())
				CPT.reload();
		}
	},
	
	setValueNode : function(node){
		var text = node.text;
		this.lastSelectionText = text;
		/*自定义----start*/
		var nodeId;
		if(this.unId){ 
			  nodeId=node.attributes[this.unId];
		}else{
			  nodeId=node.id;
		}  
		/*当进行选择时，还要对某些隐藏字段进行设置值时,这个地方不是特别的好。*/
		if(this.hiddenField){
			  Ext.getCmp(this.hiddenField).setValue(nodeId);
			  //this.hiddenField.setValue(nodeId);
		}
		/*自定义----end*/
		Ext.form.ComboBox.superclass.setValue.call(this, text);
		this.value = nodeId;
	}, 
	getValue : function(){
		return typeof this.value != 'undefined' ? this.value : '';
	}
});

Ext.reg('combotree', Ext.ux.ComboBoxTree);
 
Ext.ux.CheckTreeCombo = function(config){
	config = config || {};
	var base = {
		tpl : new Ext.Template(''), //使用一个空模板代替预设
		store : Hxcy.Factory['EmptyStore'],//使用一个空的Store使用组件能正常运作
		selectedClass : '',
		mode : 'local',
		triggerAction : 'all',
		onSelect : Ext.emptyFn,
		nodeId : 'id',
		nodeText : 'text',
		editable : false,
		readOnly : true
	};
	Ext.applyIf(config, base);
	
	Ext.ux.CheckTreeCombo.superclass.constructor.call(this, config);
}

Ext.extend(Ext.ux.CheckTreeCombo,Ext.form.ComboBox, {
	
	expand : function(){
		Ext.ux.CheckTreeCombo.superclass.expand.call(this);
		if(!this.tree.rendered){
			//这个地方主要是为了将store与视图脱离关系,这一点很重根,如果不这样,当对store进行操作时会将树结构清空
			this.view.bindStore(null);
			var treeCfg = this.tree;
			delete this.tree;

			treeBase = {};
			treeBase.height = this.maxHeight;
			treeBase.width = this.listWidth ? this.listwidth-2 : '';
			treeBase.width = !treeCfg.width && this.width ? this.width-4 : '';
			treeBase.border=false;
			treeBase.autoScroll=true;
			treeBase.xtype = 'checktreepanel';
			treeBase.animate = true;
			treeBase.enableDD = false;
			treeBase.containerScroll = true;
			treeBase.CPTVisible = true;
			
			Ext.applyIf(treeCfg, treeBase);
			//创建树组件对象
			this.tree = Ext.ComponentMgr.create(treeCfg, treeCfg.xtype);
			//渲染树组件
			this.tree.render(this.innerList);
			var combox = this;
			this.tree.on('checkchange',this.onCheckChange, this);
			if (this.clickcheck!==false) {
				this.tree.on('click', this.onNodeClick, this);
			}
		}
	},
	onViewClick : Ext.emptyFn,
	beforeBlur : Ext.emptyFn,//阻止在失去焦点时重新设置值
	onCheckChange : function(node, b){
		var text = node.text;
		var ids = this.tree.getChecked(this.nodeId);
		var texts = this.tree.getChecked(this.nodeText);
		this.lastSelectionText = text;
		if(this.hiddenField){
			this.hiddenField.value = ids;
		}
		Ext.form.ComboBox.superclass.setValue.call(this, texts);
		this.value = ids;
	},
	
	onNodeClick : function(node, e){
		if (this.tree.onlyLeafCheckable!==true||node.isLeaf()) {
			node.ui.onCheckboxClick(e, node);
		}
	},
	
	reset : function(){
		Ext.ux.CheckTreeCombo.superclass.reset.call(this);
		if(this.tree.rendered && this.tree.CPT.ui.resetChecked){
			this.tree.CPT.ui.resetChecked();
		}
	},
	
	setValue : function(v){
		var text = v;
		if(this.valueField){
			var r = this.findRecord(this.valueField, v);
			if(r){
				text = r.data[this.displayField];
			}else if(Ext.isDefined(this.valueNotFoundText)){
				text = this.valueNotFoundText;
			}
		}
		this.lastSelectionText = text;
		if(this.hiddenField){
			this.hiddenField.value = v;
		}
		text = text=='null' ? '' : text;
		Ext.form.ComboBox.superclass.setValue.call(this, text);
		this.value = v;
		return this;
	}
});

Ext.reg('checktreecombo', Ext.ux.CheckTreeCombo);

Ext.ux.TimeField=function(config)
{
	//be true when reset

	this.dateTime=config.dateTime;
	Ext.ux.TimeField.superclass.constructor.call(this,config);
};

Ext.extend(Ext.ux.TimeField,Ext.form.TimeField, {
	 
	 /**//**
	 * Clear any invalid styles/messages for this field
	 */
	clearInvalid : function(){
		if(!this.rendered || this.preventMark){ // not rendered
			return;
		}
		this.el.removeClass(this.invalidClass);
		this.dateTime.clearInvalid();
		//check the other field for datetime
		//this.dateTime.df.isValid();
		
	},
	/**//**
	 * Mark this field as invalid
	 * @param {String} msg The validation message
	 */
	markInvalid : function(msg){
		if(!this.rendered || this.preventMark){ // not rendered
			return;
		}
		this.el.addClass(this.invalidClass);
		msg = msg || this.invalidText;
		this.dateTime.markInvalid(msg);
	}
});

Ext.ux.TabCloseMenu = function(){
	var tabs, menu, ctxItem;
	this.init = function(tp){
		tabs = tp;
		tabs.on('contextmenu', onContextMenu);
	}

	function onContextMenu(ts, item, e){
		if(!menu){ // create context menu on first right click
			menu = new Ext.menu.Menu([{
				id: tabs.id + '-close',
				text: '关闭当前标签',
				iconCls : 'ok',
				handler : function(){
					tabs.remove(ctxItem);
				}
			},{
				id: tabs.id + '-close-others',
				iconCls : 'delete',
				text: '关闭其它标签',
				handler : function(){
					tabs.items.each(function(item){
						if(item.closable && item != ctxItem){
							tabs.remove(item);
						}
					});
				}
			}]);
		}
		ctxItem = item;
		var items = menu.items;
		items.get(tabs.id + '-close').setDisabled(!item.closable);
		var disableOthers = true;
		tabs.items.each(function(){
			if(this != item && this.closable){
				disableOthers = false;
				return false;
			}
		});
		items.get(tabs.id + '-close-others').setDisabled(disableOthers);
		menu.showAt(e.getPoint());
	}
};

/*
 * 用来输入时间控件的开始时间，结束时间，以及密码的确认
 */

Ext.apply(Ext.form.VTypes, {
	daterange : function(val, field) {
		var date = field.parseDate(val);

		if(!date){
			return;
		}
		if (field.startDateField && (!this.dateRangeMax || (date.getTime() != this.dateRangeMax.getTime()))) {
			var start = Ext.getCmp(field.startDateField);
			start.setMaxValue(date);
			start.validate();
			this.dateRangeMax = date;
		} 
		else if (field.endDateField && (!this.dateRangeMin || (date.getTime() != this.dateRangeMin.getTime()))) {
			var end = Ext.getCmp(field.endDateField);
			end.setMinValue(date);
			end.validate();
			this.dateRangeMin = date;
		}
		return true;
	},

	password : function(val, field) {
		if (field.initialPassField) {
			var pwd = Ext.getCmp(field.initialPassField);
			return (val == pwd.getValue());
		}
		return true;
	},

	passwordText : 'Passwords do not match'
});

/**
 * 在表格对某例以进度表的方式表示,扩展
 */

Ext.namespace('Ext.ux.grid');

Ext.ux.grid.ProgressColumn = function(config) {
  Ext.apply(this, config);
  this.renderer = this.renderer.createDelegate(this);
  this.addEvents('action');
  Ext.ux.grid.ProgressColumn.superclass.constructor.call(this);
};

Ext.extend(Ext.ux.grid.ProgressColumn, Ext.util.Observable, {
  /**
   * @cfg {String} colored determines whether use special progression coloring
   *      or the standard Ext.ProgressBar coloring for the bar (defaults to
   *      false)
   */
  textPst : '%',
  /**
   * @cfg {String} colored determines whether use special progression coloring
   *      or the standard Ext.ProgressBar coloring for the bar (defaults to
   *      false)
   */
  colored : false,
  /**
   * @cfg {String} actionEvent Event to trigger actions, e.g. click, dblclick,
   *      mouseover (defaults to 'dblclick')
   */
  actionEvent : 'dblclick',

  init : function(grid) {
    this.grid = grid;
    this.view = grid.getView();

    if (this.editor && grid.isEditor) {
      var cfg = {
        scope : this
      };
      cfg[this.actionEvent] = this.onClick;
      grid.afterRender = grid.afterRender.createSequence(function() {
        this.view.mainBody.on(cfg);
      }, this);
    }
  },

  onClick : function(e, target) {
    var rowIndex = e.getTarget('.x-grid3-row').rowIndex;
    var colIndex = this.view.findCellIndex(target.parentNode.parentNode);

    var t = e.getTarget('.x-progress-text');
    if (t) {
      this.grid.startEditing(rowIndex, colIndex);
    }
  },

  renderer : function(v, p, record) {
    var style = '';
    var textClass = (v < 55) ? 'x-progress-text-back' : 'x-progress-text-front' + (Ext.isIE6 ? '-ie6' : '');

    //ugly hack to deal with IE6 issue
    var text = String.format('</div><div class="x-progress-text {0}" style="width:100%;" id="{1}">{2}</div></div>',
      textClass, Ext.id(), v+0 + this.textPst
    );
    text = (v<96) ? text.substring(0, text.length - 6) : text.substr(6);

if (this.colored == true) {
      if (v <= 100 && v > 33)
        style = '-orange';
//      if (v < 67 && v > 33)
//        style = '-orange';
      if (v < 34)
        style = '-red';
    }

    p.css += ' x-grid3-progresscol';
    return String.format(
      '<div class="x-progress-wrap"><div class="x-progress-inner"><div class="x-progress-bar{0}" style="width:{1}%;">{2}</div>' +
      '</div>', style, v>100?100:v, text
    );
  }
});


Hxcy.UploadPanel = Ext.extend(Ext.Panel, {
	//文件列表
	fileList : null,
	//核心上传对象
	swfupload : null,
	//进度条
	progressBar : null,
	//进度信息
	progressInfo : null,
	//上传信息面板
	uploadInfoPanel : null,
	constructor : function(config) {
		//进度信息对象
		this.progressInfo = {
			filesTotal : 0,
			filesUploaded : 0,
			bytesTotal : 0,
			bytesUploaded : 0,
			currentCompleteBytes : 0,
			lastBytes : 0,
			lastElapsed : 1,
			lastUpdate : null,
			timeElapsed : 1
		};
		//上传信息面板
		this.uploadInfoPanel = new Ext.Panel({
			region : 'north',
			hidden : true,
			height : 65,
			baseCls : '',
			collapseMode : 'mini',
			split : true,
			border : false
		});
		//进度条对象
		this.progressBar = new Ext.ProgressBar({
			hidden : true,
			text : '等待中 0 %',
			animate : true
		});
		//自动展开的列标识
		var autoExpandColumnId = Ext.id('fileName');
		//更新上传信息面板
		this.uploadInfoPanel.on('render', function() {
			this.getProgressTemplate().overwrite(this.uploadInfoPanel.body, {
				filesUploaded : 0,
				filesTotal : 0,
				bytesUploaded : '0 bytes',
				bytesTotal : '0 bytes',
				timeElapsed : '00:00:00',
				timeLeft : '00:00:00',
				speedLast : '0 bytes/s',
				speedAverage : '0 bytes/s'
			});
		}, this);
		
		//文件列表面板
		this.fileList = new Ext.grid.GridPanel({
			border : false,
			enableColumnMove : false,
			enableHdMenu : false,
			columns : [new Ext.grid.RowNumberer(), {
				header : '文件名',
				width : 100,
				dataIndex : 'fileName',
				sortable : false,
				fixed : true,
				renderer : this.formatFileName,
				id : autoExpandColumnId
			}, {
				header : '大小',
				width : 80,
				dataIndex : 'fileSize',
				sortable : false,
				fixed : true,
				renderer : this.formatFileSize,
				align : 'right'
			}, {
				header : '类型',
				width : 60,
				dataIndex : 'fileType',
				sortable : false,
				fixed : true,
				renderer : this.formatIcon,
				align : 'center'
			}, {
				header : '进度',
				width : 100,
				dataIndex : '',
				sortable : false,
				fixed : true,
				renderer : this.formatProgressBar,
				align : 'center'
			}, {
				header : '&nbsp;',
				width : 28,
				dataIndex : 'fileState',
				renderer : this.formatState,
				sortable : false,
				fixed : true,
				align : 'center'
			}],
			autoExpandColumn : autoExpandColumnId,
			ds : new Ext.data.SimpleStore({
				fields : ['fileId', 'fileName', 'fileSize', 'fileType', 'fileState']
			}),
			bbar : [this.progressBar],
			tbar : [{
				//此处理的实际功能应该由影片剪辑来完成
				text : '添加文件',
				iconCls : 'db-icn-add'
			}, {
				text : '开始上传',
				iconCls : 'db-icn-upload_',
				handler : this.startUpload,
				scope : this
			}, {
				text : '停止上传',
				iconCls : 'db-icn-stop',
				hidden : true,
				handler : this.stopUpload,
				scope : this
			}, {
				text : '取消队列',
				hidden : true,
				iconCls : 'db-icn-cross',
				handler : this.cancelQueue,
				scope : this
			}, {
				text : '清空列表',
				iconCls : 'db-icn-trash',
				handler : this.clearList,
				scope : this
			}],
			errorTip : new Ext.Tip({html:'测试'}),
			listeners : {
				cellclick : {
					fn : function(grid, rowIndex, columnIndex, e) {
						if (columnIndex == 5) {
							var record = grid.getSelectionModel().getSelected();
							var fileId = record.data.fileId;
							var file = this.swfupload.getFile(fileId);
							if (file) {
								if (file.filestatus != SWFUpload.FILE_STATUS.CANCELLED) {
									this.swfupload.cancelUpload(fileId);
									if (record.data.fileState != SWFUpload.FILE_STATUS.CANCELLED) {
										record.set('fileState', SWFUpload.FILE_STATUS.CANCELLED);
										record.commit();
										this.onCancelQueue(fileId);
									}
								}
							}
						}
					},
					scope : this
				},
				render : {
					fn : function() {
						//获取网格面板
						var grid = this.get(1).get(0);
						//获取添加按钮
						var em = grid.getTopToolbar().get(0).el.child('em');
						var placeHolderId = Ext.id();
						em.setStyle({
							position : 'relative',
							display : 'block'
						});
						//创建影片剪辑的容器
						em.createChild({
							tag : 'div',
							id : placeHolderId
						});
						//影片剪辑的设置
						var settings = {
							upload_url : this.uploadUrl,
							//其它需要上传的参数
							post_params : Ext.isEmpty(this.postParams) ? {} : this.postParams,
							flash_url : Ext.isEmpty(this.flashUrl) ? Hxcy.CPT+'/public/script/swfu/v25/core/swfupload_fp10/swfupload.swf' : this.flashUrl,
							flash9_url : Hxcy.CPT+'/public/script/swfu/v25/core/swfupload_fp9/swfupload_fp9.swf',
							//上传时的文件字段名
							file_post_name : Ext.isEmpty(this.filePostName) ? 'upload' : this.filePostName,
							//文件大小限制
							file_size_limit : Ext.isEmpty(this.fileSize) ? '100 MB' : this.fileSize,
							//文件类型限制
							file_types : Ext.isEmpty(this.fileTypes) ? '*.*' : this.fileTypes,
							//文件类型描述
							file_types_description : this.fileTypesDescription,
							//设置其它参数上传方式GET
							use_query_string : true,
							//是否打开调试
							debug : false,
							button_width : '73',
							button_height : '20',
							button_placeholder_id : placeHolderId,
							//影片剪辑的模式为透明
							button_window_mode : SWFUpload.WINDOW_MODE.TRANSPARENT,
							button_cursor : SWFUpload.CURSOR.HAND,
							custom_settings : {
								scope_handler : this
							},
							//文件添加成功的处理器
							file_queued_handler : this.onFileQueued,
							//文件添加错误的处理器
							file_queue_error_handler : this.onFileQueueError,
							//文件添加对象框架关闭的处理器
							file_dialog_complete_handler : this.onFileDialogComplete,
							//开始上传的处理器
							upload_start_handler : this.onUploadStart,
							//进度更新处理处理器
							upload_progress_handler : this.onUploadProgress,
							//上传错误处理器
							upload_error_handler : this.onUploadError,
							//上传成功处理器
							upload_success_handler : this.onUploadSuccess,
							//上传完成的处理器
							upload_complete_handler : this.onUploadComplete
						};
						//构建影片剪辑对象
						this.swfupload = new SWFUpload(settings);
						//上传对象没有这个属性???
						this.swfupload.uploadStopped = false;
						//设置影片剪辑与添加按钮的相对位置
						Ext.get(this.swfupload.movieName).setStyle({
							position : 'absolute',
							top : 0,
							left : -2
						});
						//设置进度条大小
						this.resizeProgressBar();
						//监听进度条大小改变
						this.on('resize', this.resizeProgressBar, this);
					},
					scope : this,
					delay : 100
				}
			}

		});
		//调用超类构造方法完成布局
		Hxcy.UploadPanel.superclass.constructor.call(this, Ext.applyIf(config || {}, {
			layout : 'border',
			width : 500,
			height : 500,
			minWidth : 450,
			minHeight : 500,
			split : true,
			items : [this.uploadInfoPanel, {
				region : 'center',
				layout : 'fit',
				margins : '0 -1 -1 -1',
				items : [this.fileList]
			}]
		}));
	},
	resizeProgressBar : function() {
		this.progressBar.setWidth(this.el.getWidth() - 5);
	},
	
	//监听开始上传
	startUpload : function() {
		if (this.swfupload) {
			//表示上传中...
			this.swfupload.uploadStopped = false;
			var post_params = this.swfupload.settings.post_params;
			// console.log(post_params);
			// post_params.path = encodeURI(this.scope.currentPath + '\\');
			// this.swfupload.setPostParams(post_params);
			this.swfupload.startUpload();
		}
	},
	//停止上传
	stopUpload : function() {
		if (this.swfupload) {
			//表示已经停止
			this.swfupload.uploadStopped = true;
			this.swfupload.stopUpload();
		}
	},
	//取消队列
	cancelQueue : function() {
		if (this.swfupload) {
			//先停止上传
			this.swfupload.stopUpload();
			//获取全局统计
			var stats = this.swfupload.getStats();
			while (stats.files_queued > 0) {
				//循环取消所有上传队列
				this.swfupload.cancelUpload();
				stats = this.swfupload.getStats();
			}
			
			this.fileList.getStore().each(function(record) {
				switch (record.data.fileState) {
					case SWFUpload.FILE_STATUS.QUEUED :
					case SWFUpload.FILE_STATUS.IN_PROGRESS :
						record.set('fileState', SWFUpload.FILE_STATUS.CANCELLED);
						record.commit();
						//取消指标的记录
						this.onCancelQueue(record.data.fileId);
						break;
					default :
						break;
				}
			}, this);
		}
	},
	clearList : function() {
		this.cancelQueue();
		var store = this.fileList.getStore();
		store.each(function(record) {
			//删除那些还没有上传的文件
			if (record.data.fileState != SWFUpload.FILE_STATUS.QUEUED
					&& record.data.fileState != SWFUpload.FILE_STATUS.IN_PROGRESS) {
				store.remove(record);
			}
		});
	},
	
	//这个地方有明显的失误,这个地方应该缓存模板对象
	getProgressTemplate : function() {
		if(!Hxcy.UploadPanel.tpl){
			var tpl = new Ext.Template('<table class="upload-progress-table"><tbody>',
					'<tr><td class="upload-progress-label"><nobr>已上传数:</nobr></td>',
					'<td class="upload-progress-value"><nobr>{filesUploaded} / {filesTotal}</nobr></td>',
					'<td class="upload-progress-label"><nobr>上传状态:</nobr></td>',
					'<td class="upload-progress-value"><nobr>{bytesUploaded} / {bytesTotal}</nobr></td></tr>',
					'<tr><td class="upload-progress-label"><nobr>已用时间:</nobr></td>',
					'<td class="upload-progress-value"><nobr>{timeElapsed}</nobr></td>',
					'<td class="upload-progress-label"><nobr>剩余时间:</nobr></td>',
					'<td class="upload-progress-value"><nobr>{timeLeft}</nobr></td></tr>',
					'<tr><td class="upload-progress-label"><nobr>当前速度:</nobr></td>',
					'<td class="upload-progress-value"><nobr>{speedLast}</nobr></td>',
					'<td class="upload-progress-label"><nobr>平均速度:</nobr></td>',
					'<td class="upload-progress-value"><nobr>{speedAverage}</nobr></td></tr>', '</tbody></table>');
			Hxcy.UploadPanel.tpl = tpl.compile();
		}
		return Hxcy.UploadPanel.tpl;
	},
	//更新进度信息
	updateProgressInfo : function() {
		this.getProgressTemplate().overwrite(this.uploadInfoPanel.body, this.formatProgress(this.progressInfo));
	},
	
	formatProgress : function(info) {
		var r = {};
		r.filesUploaded = String.leftPad(info.filesUploaded, 3, '&nbsp;');
		r.filesTotal = info.filesTotal;
		r.bytesUploaded = String.leftPad(Ext.util.Format.fileSize(info.bytesUploaded), 6, '&#160;');
		r.bytesTotal = Ext.util.Format.fileSize(info.bytesTotal);
		r.timeElapsed = this.formatTime(info.timeElapsed);
		r.speedAverage = Ext.util.Format.fileSize(Math.ceil(1000 * info.bytesUploaded / info.timeElapsed)) + '/s';
		r.timeLeft = this.formatTime((info.bytesUploaded === 0) ? 0 : info.timeElapsed
				* (info.bytesTotal - info.bytesUploaded) / info.bytesUploaded);
		var caleSpeed = 1000 * info.lastBytes / info.lastElapsed;
		r.speedLast = Ext.util.Format.fileSize(caleSpeed < 0 ? 0 : caleSpeed) + '/s';
		var p = info.bytesUploaded / info.bytesTotal;
		p = p || 0;
		this.progressBar.updateProgress(p, "上传中 " + Math.ceil(p * 100) + " %");
		return r;
	},
	formatTime : function(milliseconds) {
		var seconds = parseInt(milliseconds / 1000, 10);
		var s = 0;
		var m = 0;
		var h = 0;
		if (3599 < seconds) {
			h = parseInt(seconds / 3600, 10);
			seconds -= h * 3600;
		}
		if (59 < seconds) {
			m = parseInt(seconds / 60, 10);
			seconds -= m * 60;
		}
		m = String.leftPad(m, 2, '0');
		h = String.leftPad(h, 2, '0');
		s = String.leftPad(seconds, 2, '0');
		return h + ':' + m + ':' + s;
	},
	formatFileSize : function(_v, celmeta, record) {
		return '<div id="fileSize_' + record.data.fileId + '">' + Ext.util.Format.fileSize(_v) + '</div>';
	},
	formatFileName : function(_v, cellmeta, record) {
		return '<div id="fileName_' + record.data.fileId + '">' + _v + '</div>';
	},
	formatIcon : function(_v, cellmeta, record) {
		var returnValue = '';
		var extensionName = _v.substring(1);
		var fileId = record.data.fileId;
		if (_v) {
			var css = '.db-ft-' + extensionName.toLowerCase() + '-small';
			if (Ext.isEmpty(Ext.util.CSS.getRule(css), true)) { // 判断样式是否存在
				returnValue = '<div id="fileType_' + fileId
						+ '" class="db-ft-unknown-small" style="height: 16px;background-repeat: no-repeat;">'
						+ '&nbsp;&nbsp;&nbsp;&nbsp;' + extensionName.toUpperCase() + '</div>';
			} else {
				returnValue = '<div id="fileType_' + fileId + '" class="db-ft-' + extensionName.toLowerCase()
						+ '-small" style="height: 16px;background-repeat: no-repeat;"/>&nbsp;&nbsp;&nbsp;&nbsp;'
						+ extensionName.toUpperCase();
				+'</div>';
			}
			return returnValue;
		}
		return '<div id="fileType_'
				+ fileId
				+ '" class="db-ft-unknown-small" style="height: 16px;background-repeat: no-repeat;"/>&nbsp;&nbsp;&nbsp;&nbsp;'
				+ extensionName.toUpperCase() + '</div>';
	},
	formatProgressBar : function(_v, cellmeta, record) {
		var returnValue = '';
		switch (record.data.fileState) {
			case SWFUpload.FILE_STATUS.COMPLETE :
				if (Ext.isIE) {
					returnValue = '<div class="x-progress-wrap" style="height: 18px">'
							+ '<div class="x-progress-inner">'
							+ '<div style="width: 100%;" class="x-progress-bar x-progress-text">' + '100 %'
					'</div>' + '</div>' + '</div>';
				} else {
					returnValue = '<div class="x-progress-wrap" style="height: 18px">'
							+ '<div class="x-progress-inner">' + '<div id="progressBar_' + record.data.fileId
							+ '" style="width: 100%;" class="x-progress-bar">' + '</div>' + '<div id="progressText_'
							+ record.data.fileId
							+ '" style="width: 100%;" class="x-progress-text x-progress-text-back" />100 %</div>'
					'</div>' + '</div>';
				}
				break;
			default :
				returnValue = '<div class="x-progress-wrap" style="height: 18px">' + '<div class="x-progress-inner">'
						+ '<div id="progressBar_' + record.data.fileId + '" style="width: 0%;" class="x-progress-bar">'
						+ '</div>' + '<div id="progressText_' + record.data.fileId
						+ '" style="width: 100%;" class="x-progress-text x-progress-text-back" />0 %</div>'
				'</div>' + '</div>';
				break;
		}
		return returnValue;
	},
	formatState : function(_v, cellmeta, record) {
		var returnValue = '';
		switch (_v) {
			case SWFUpload.FILE_STATUS.QUEUED :
				returnValue = '<span id="' + record.id + '"><div id="fileId_' + record.data.fileId
						+ '" class="ux-cell-icon-upload" qtip="'+record.get('serverData')+'"/></span>';
				break;
			case SWFUpload.FILE_STATUS.ERROR :
				returnValue = '<span id="' + record.id + '"><div id="fileId_' + record.data.fileId
						+ '" class="ux-cell-icon-delete" qtip="'+record.get('serverData')+'"/></span>';
				break;
			case SWFUpload.FILE_STATUS.CANCELLED :
				returnValue = '<span id="' + record.id + '"><div id="fileId_' + record.data.fileId
						+ '" class="ux-cell-icon-clear" qtip="'+record.get('serverData')+'"/></span>';
				break;
			case SWFUpload.FILE_STATUS.COMPLETE :
				if(record.get('serverData')=='导入成功'){
					returnValue = '<span id="' + record.id + '"><div id="fileId_' + record.data.fileId
							+ '" class="ux-cell-icon-completed" qtip="'+record.get('serverData')+'"/></span>';
				} else {
					returnValue = '<span id="' + record.id + '"><div id="fileId_' + record.data.fileId
						+ '" class="ux-cell-icon-delete" qtip="'+record.get('serverData')+'"/></span>';
				}
				break;
			default :
				alert('没有设置图表状态');
				break;
		}
		return returnValue;
	},
	onClose : function() {
		this.close();
	},
	onCancelQueue : function(fileId) {
		Ext.getDom('fileName_' + fileId).className = 'ux-cell-color-gray';// 设置文字颜色为灰色
		Ext.getDom('fileSize_' + fileId).className = 'ux-cell-color-gray';
		Ext.DomHelper.applyStyles('fileType_' + fileId, 'font-style:italic;text-decoration: line-through;color:gray');
	},
	//当文件添加到网格中后回调
	onFileQueued : function(file) {
		var thiz = this.customSettings.scope_handler;
		thiz.fileList.getStore().add(new Hxcy.UploadPanel.FileRecord({
			fileId : file.id,
			fileName : file.name,
			fileSize : file.size,
			fileType : file.type,
			fileState : file.filestatus,
			serverData : ''
		}));
		thiz.progressInfo.filesTotal += 1;
		thiz.progressInfo.bytesTotal += file.size;
		thiz.updateProgressInfo();
	},
	onQueueError : function(file, errorCode, message) {
		var thiz = this.customSettings.scope_handler;
		try {
			if (errorCode != SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED) {
				thiz.progressInfo.filesTotal -= 1;
				thiz.progressInfo.bytesTotal -= file.size;
			}
			thiz.progressInfo.bytesUploaded -= fpg.getBytesCompleted();
			thiz.updateProgressInfo();
		} catch (ex) {
			this.debug(ex);
		}
	},
	onFileDialogComplete : function(selectedFilesCount, queuedFilesCount) {
		// alert("selectedFilesCount:" + selectedFilesCount + "
		// queuedFilesCount:" + queuedFilesCount );
	},
	onUploadStart : function(file) {
	},
	onUploadProgress : function(file, completeBytes, bytesTotal) {
		var percent = Math.ceil((completeBytes / bytesTotal) * 100);
		Ext.getDom('progressBar_' + file.id).style.width = percent + "%";
		Ext.getDom('progressText_' + file.id).innerHTML = percent + " %";

		var thiz = this.customSettings.scope_handler;
		var bytes_added = completeBytes - thiz.progressInfo.currentCompleteBytes;
		thiz.progressInfo.bytesUploaded += Math.abs(bytes_added < 0 ? 0 : bytes_added);
		thiz.progressInfo.currentCompleteBytes = completeBytes;
		if (thiz.progressInfo.lastUpdate) {
			thiz.progressInfo.lastElapsed = thiz.progressInfo.lastUpdate.getElapsed();
			thiz.progressInfo.timeElapsed += thiz.progressInfo.lastElapsed;
		}
		thiz.progressInfo.lastBytes = bytes_added;
		thiz.progressInfo.lastUpdate = new Date();
		thiz.updateProgressInfo();
	},
	onUploadError : function(file, errorCode, message) {
		var thiz = this.customSettings.scope_handler;
		switch (errorCode) {
			case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED :
				thiz.progressInfo.filesTotal -= 1;
				thiz.progressInfo.bytesTotal -= file.size;
				thiz.updateProgressInfo();
				break;
			case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED :
		}
	},
	onUploadSuccess : function(file, serverData) {
		var thiz = this.customSettings.scope_handler;
		var serverData = Ext.util.JSON.decode(serverData);
		var record = thiz.fileList.getStore().getById(Ext.getDom('fileId_' + file.id).parentNode.id);
		if (serverData.success) {
			record.set('fileState', file.filestatus);
			record.set('serverData', '导入成功')
			record.commit();
		} else {
			record.set('fileState', file.filestatus);
			record.set('serverData', serverData['actionErrors'][0]);
			record.commit();
		}
		thiz.progressInfo.filesUploaded += 1;
		thiz.updateProgressInfo();
	},
	onUploadComplete : function(file) {
		//如果还存在没有上传的文件,且已经停止上传,则下始下一个文件的上传
		if (this.getStats().files_queued > 0 && this.uploadStopped == false) {
			this.startUpload();
		} else {//所有文件上传完成
			var thiz = this.customSettings.scope_handler;
			thiz.fireEvent('allfileuploaded', thiz, file);//这里的
		}
	}
});

Hxcy.UploadPanel.FileRecord = Ext.data.Record.create([{
	name : 'fileId'
}, {
	name : 'fileName'
}, {
	name : 'fileSize'
}, {
	name : 'fileType'
}, {
	name : 'fileState'
}, {
	name : 'serverData'
}]);

Ext.reg('Hxcyuploadpanel', Hxcy.UploadPanel);

